Перебора структура поля в 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'.

Я не могу разобраться в этом.

4 ответов


вы должны использовать фигурные скобки ({}) к fields С fieldnames


С 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

ваш fns является массивом cellstr. Вам нужно индексировать его с помощью {} вместо (), чтобы получить одну строку как char.

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

индексирование в нем с помощью () возвращает массив cellstr длиной 1, который не имеет того же формата, что и массив char, который".(name) " требуется динамическая ссылка на поле. Форматирование, особенно в выводе дисплея, может быть запутанным. Чтобы увидеть разницу, попробуйте это.

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

можно использовать для каждого из элементов 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

мне очень нравится. Кредит, конечно, перейти к Джереми Хьюз, который разработал инструментарий.