在MATLAB中迭代结构体字段名

77

我的问题可以简单概括为:"为什么以下代码无法运行?"

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')是可以工作的。而且fields(i)打印出ans = 'a'

我无法理解它。

4个回答

98

要访问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

2
你的答案非常有帮助,解决了我多年来一直困扰的问题。 - Mad Physicist

16

由于fieldsfns是单元数组,因此必须使用花括号{}进行索引,以访问单元格的内容,即字符串。

请注意,您也可以直接循环遍历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

5

您的fns是一个cellstr数组。您需要使用{}而不是()对其进行索引,以获取单个字符串作为char。

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

使用()索引它会返回一个长度为1的cellstr数组,这与“.(name)”动态字段引用所需要的char数组格式不同。特别是在显示输出方面,格式可能会让人感到困惑。要了解差异,请尝试以下操作。

name_as_char = 'a'
name_as_cellstr = {'a'}

1
你可以使用 http://www.mathworks.com/matlabcentral/fileexchange/48729-for-each 中的 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。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接