web-dev-qa-db-ja.com

MATLABでのstructフィールド名の繰り返し

私の質問は次のように簡単に要約できます: "なぜ以下は機能しないのですか?"

_teststruct = struct('a',3,'b',5,'c',9)

fields = fieldnames(teststruct)

for i=1:numel(fields)
  fields(i)
  teststruct.(fields(i))
end
_

出力:

_ans = 'a'

??? Argument to dynamic structure reference must evaluate to a valid field name.
_

特にteststruct.('a')doesが機能するため。そして、fields(i)は_ans = 'a'_を出力します。

私はそれを回避できません。

68
noio

中括弧({}fieldsにアクセスするには、 fieldnames 関数が文字列の セル配列 を返すため、

for i = 1:numel(fields)
  teststruct.(fields{i})
end

セル配列のデータにアクセスする に括弧を使用すると、文字配列とは異なる表示の別のセル配列が返されます。

>> fields(1)  % Get the first cell of the cell array

ans = 

    'a'       % This is how the 1-element cell array is displayed

>> fields{1}  % Get the contents of the first cell of the cell array

ans =

a             % This is how the single character is displayed
89
gnovice

fieldsまたはfnsはセル配列であるため、中括弧{}セルのコンテンツ、つまり文字列にアクセスするため。

数値をループする代わりに、fieldsを直接ループすることもできます。これは、任意の配列をループできる、すてきなMatlab機能を利用します。反復変数は、配列の各列の値を取ります。

teststruct = struct('a',3,'b',5,'c',9)

fields = fieldnames(teststruct)

for fn=fields'
  fn
  %# since fn is a 1-by-1 cell array, you still need to index into it, unfortunately
  teststruct.(fn{1})
end
15
Jonas

Fnsはcellstr配列です。単一の文字列をcharとして取得するには、()の代わりに{}でインデックスを作成する必要があります。

fns{i}
teststruct.(fns{i})

()でインデックスを作成すると、1つの長さのcellstr配列が返されます。これは、「。(name)」動的フィールド参照が必要とするchar配列と同じ形式ではありません。特に表示出力での書式設定はわかりにくい場合があります。違いを確認するには、これを試してください。

name_as_char = 'a'
name_as_cellstr = {'a'}
5
Andrew Janke

http://www.mathworks.com/matlabcentral/fileexchange/48729-for-each から各ツールボックスのを使用できます。

>> signal
signal = 
sin: {{1x1x25 cell}  {1x1x25 cell}}
cos: {{1x1x25 cell}  {1x1x25 cell}}

>> each(fieldnames(signal))
ans = 
CellIterator with properties:

NumberOfIterations: 2.0000e+000

使用法:

for bridge = each(fieldnames(signal))
   signal.(bridge) = Rand(10);
end

私はそれがとても好き。もちろん、ツールボックスを開発したJeremy Hughesに感謝します。

0
Jan