35

我有一个包含许多字段的结构,这些字段是不同长度的向量。我想按顺序访问循环内的字段。我按如下方式尝试了 getfield,但 MATLAB 不喜欢这样。我怎样才能做到这一点?

S = struct('A', [1 2], 'B',[3 4 5]);
SNames = fieldnames(S);
for loopIndex = 1:2
  field = getfield(S, SNames(loopIndex));
  %do stuff w/ field
end
??? Index exceeds matrix dimensions

我首先使用结构,因为数组会遇到不同字段长度的问题。有没有更好的选择?

4

6 回答 6

46

尝试动态字段引用,将字符串放在括号中,如定义stuff的行中所示。

S = struct('A', [1 2], 'B',[3 4 5]); 
SNames = fieldnames(S); 
for loopIndex = 1:numel(SNames) 
    stuff = S.(SNames{loopIndex})
end 

我同意史蒂夫和亚当的观点。使用细胞。不过,这种语法适用于其他情况下的人!

于 2009-12-10T16:31:45.903 回答
16

我想在这里提出三点:

  • 您在上面的代码中遇到错误的原因是您的索引方式SNames。该函数fieldnames返回一个字符串元胞数组,因此您必须使用内容索引(即花括号)来访问字符串值。如果将代码中的第四行更改为:

    field = getfield(S, SNames{loopIndex});
    

    那么您的代码应该可以正常工作。

  • 正如MatlabDoug所建议的那样,您可以使用动态字段名称来避免使用getfield(在我看来,这会产生更清晰的代码)。

  • Adam提出的使用元胞数组而不是结构体的建议是正确的。这通常是将一系列不同长度的数组收集到单个变量中的最佳方法。您的代码最终看起来像这样:

    S = {[1 2], [3 4 5]};        % Create the cell array
    for loopIndex = 1:numel(S)   % Loop over the number of cells
      array = S{loopIndex};      % Access the contents of each cell
      % Do stuff with array
    end
    
于 2009-12-10T18:26:34.360 回答
5

getfield 方法没问题(尽管我现在没有可用的 MATLAB,而且我不清楚为什么上述方法不起作用)。

对于另一种数据结构,您可能还需要查看 MATLAB 元胞数组。它们还允许您存储和索引不同长度的向量。

于 2009-12-10T16:11:05.040 回答
2

您可以使用冒号表示法来避免索引:

S = struct('A', [1 2], 'B',[3 4 5]); 
SNames = fieldnames(S); 
for SName = [SNames{:}]
    stuff = S.(SName)
end
于 2012-12-03T15:31:24.740 回答
2

如果您需要使用一种我发现效果很好的结构,那就是首先转换为一个单元格,那么您将拥有两全其美的优势。

S = struct('A', [1 2], 'B',[3 4 5]); 
S_Cell = struct2cell(S);
%Then as per gnovice
for loopIndex = 1:numel(S_Sell)   % Loop over the number of cells
    array = S{loopIndex};         % Access the contents of each cell
    %# Do stuff with array
end

我对结构中生成的东西使用了类似的东西,然后我需要像矩阵一样访问它,在这种情况下,它就像

M = cell2mat(struct2cell(S));

将其转换为矩阵

于 2013-03-18T14:02:41.423 回答
0

只是为了添加另一个答案。我喜欢@Niver 的解决方案,但它仅适用于具有单字母名称的字段。我使用的解决方案是:

S = struct('A', [1 2], 'B',[3 4 5], 'Cee', [6 7]); 
for SName = fieldnames(S)'
    stuff = S.(SName{1})
end

for将遍历单元格数组的列(因此转置在fieldnames(S)'. 对于每个循环 SName 变为 1x1 单元格数组,因此我们使用内容索引来访问第一个也是唯一一个带有SName{1}.

于 2014-03-17T11:53:28.087 回答