У меня есть структура со многими полями, которые являются векторами разной длины. Я хотел бы получить доступ к полям внутри цикла, по порядку. Я попробовал 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
Я использую структуры в первую очередь потому, что у массива возникнут проблемы с разными полями. Есть ли лучшая альтернатива этому?
Попробуйте ссылку на динамическое поле, где вы помещаете строку в круглую скобку, как показано на строке, определяющей материал.
S = struct('A', [1 2], 'B',[3 4 5]);
SNames = fieldnames(S);
for loopIndex = 1:numel(SNames)
stuff = S.(SNames{loopIndex})
end
Я согласен со Стивом и Адамом. Используйте ячейки. Этот синтаксис подходит для людей в других ситуациях, хотя!
Есть три момента, которые я хотел бы сделать здесь:
Причина, по которой вы получаете ошибку в своем предыдущем коде, связана с тем, как вы индексируете SNames
. Функция fieldnames
возвращает массив ячеек строки, поэтому вам нужно использовать индексацию содержимого (то есть фигурные скобки) для доступа к строковым значениям. Если вы измените четвертую строку в своем коде на это:
field = getfield(S, SNames{loopIndex});
тогда ваш код должен работать без ошибок.
Как предложено MatlabDoug, вы можете использовать имена динамических полей, чтобы избежать использования getfield
(что, на мой взгляд, дает более чистый код).
Предложение от Adam вместо
Подход Getfield подходит (хотя у меня нет MATLAB, доступного прямо сейчас, и мне не ясно, почему выше не работает).
Для альтернативной структуры данных вы также можете посмотреть в массивы ячеек MATLAB. Они также позволят вам хранить и индексировать векторы различной длины.
Вы можете использовать двоеточие, чтобы избежать индексов:
S = struct('A', [1 2], 'B',[3 4 5]);
SNames = fieldnames(S);
for SName = [SNames{:}]
stuff = S.(SName)
end
Если вам нужно использовать структуру, то, что я нашел, работало очень хорошо, чтобы сначала преобразовать в ячейку, тогда у вас есть лучшее из обоих миров.
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));
Чтобы преобразовать его в матрицу
Просто добавьте еще один ответ на микс. Мне нравится решение от @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}
.