【问题标题】:Iterating through struct fieldnames in MATLAB在 MATLAB 中遍历结构字段名
【发布时间】:2011-02-17 17:43:34
【问题描述】:

我的问题很容易概括为:“为什么以下方法不起作用?”

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'

我无法理解它。

【问题讨论】:

    标签: matlab matlab-struct


    【解决方案1】:

    您必须使用花括号 ({}) 来访问 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】:

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

    【讨论】:

      【解决方案3】:

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

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

      使用 () 对其进行索引会返回一个 1 长的 cellstr 数组,它与“.(name)”动态字段引用所需的 char 数组的格式不同。格式,尤其是在显示输出中,可能会令人困惑。要查看差异,请尝试此操作。

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-27
          • 1970-01-01
          • 1970-01-01
          • 2017-03-04
          相关资源
          最近更新 更多