Перебора структура поля в 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
или 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
мне очень нравится. Кредит, конечно, перейти к Джереми Хьюз, который разработал инструментарий.