2010-05-10 97 views
58

我的问题很容易概括为:“为什么以下方法不起作用?”在MATLAB中对结构字段名进行迭代

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'

我无法理解它。

回答

75

你必须使用大括号({})来访问fields,因为fieldnames函数返回一个字符串cell array

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

使用括号access data in your cell array只会返回另一个单元阵列,这是从不同的显示一个字符数组:

>> 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

你的回答非常有帮助,并已清理了一些已经多年来一直困扰着我的东西。 – 2015-10-29 13:49:26

5

你的fns是一个cellstr数组。您需要使用{}而不是()以索引为单个字符串作为字符。

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

索引中以将其与()返回一个1-长cellstr阵列,这是不相同的格式char数组的“(名称)”的动态字段参考就是了。格式化,特别是在显示输出中,可能会造成混淆。要看到不同之处,试试这个。

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

由于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 
0

您可以从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。