2016-08-24 3 views
0

У меня есть 5 структур Matlab. Я хотел бы повторить их. Мое текущее решение заключается в следующее:Matlab: перебирать несколько структур

all_structs = [struct1,struct2,struct3,struct4,struct5]; 
for single_struct = all_structs 
    % do stuff to each struct here 
end 

Однако каждый из структур выше, имеет матрицу с большим количеством данных (в том числе некоторых других свойств). Кроме того, что бы я ни изменил в single_struct, не возвращается обратно к оригиналу struct.

Вопрос: Как это исправить? Повторяет ли Matlab все эти данные, когда я создаю вектор all_structs? Или данные из каждой из структур (struct1,...,struct5) переданы по ссылке? Есть ли лучший способ перебора нескольких структур?

Спасибо за помощь!

+0

Это звучит, как если исходная проблема в том, что структура не является массив структуры , Спонтанно я бы рекомендовал вам исправить исходную проблему. Я знаю, что иногда это может быть сложно, но в противном случае вы должны жить с этими накладными расходами, я считаю. Если вы это сделаете, то временная задержка не будет такой плохой. В ответах есть решение с 'eval', но я бы не рекомендовал его. Вы также можете сделать это пошагово, если память не удалась. – patrik

+0

@patrik Эй, это очень полезное предложение. Поэтому вместо создания группы структур я должен создать массив struct, который похож на структуру, содержащую структуры. Это оно? –

+0

Вот как это делается. Стоит отметить, что все структуры будут иметь одинаковые поля, а матрицы в этих полях будут иметь одинаковый размер. К элементу структуры можно обращаться точно как к массиву, 'numel (s (1) .a) == N; numel (s (2) .a) == N'. В случае, если матрицы имеют разные размеры, вместо этого вы должны использовать массив 'cell'. К ним обращаются с помощью оператора '{}', 'numel (c {1}) == N; numel (c {2} ~ = N) '. – patrik

ответ

3

struct не будет передан по ссылке. Вам нужно будет перебрать элементы в all_structs с помощью индекса, а затем получить доступ и изменить с помощью этого индекса. Если вам нужно что-то, что нужно рассматривать как ссылку, вам нужно будет определить класс для него и сделать наследование класса от handle. Suggested reading

for i = 1:numel(all_structs) 
    % do stuff to each struct here 
    all_structs(i).data = ones(10,5); % your code here 
end 

Я хотел бы предложить также чтение на arrayfun, хотя это полезно, если вы хотите сделать операцию и получить результаты. Из вашего описания это похоже на то, что вы хотите изменить структуры.

+0

Имейте в виду, что 'arrayfun' медленнее, чем один цикл' for'. – EBH

0

Если вы хотите изменить содержимое исходных структур, не делая копии, вы можете использовать массив ячеек структурных имен.
Затем перетащите имена и используйте eval, чтобы изменить содержание.
Использования eval неэффективно, так что не сделать это привычкой ...

Смотрите следующий пример кода:

%Create sample structs (each struct has a data element). 
struct1.data = 1; 
struct2.data = 2; 
struct3.data = 3; 

%Create a cell array containing structs names as strings. 
struct_names = {'struct1', 'struct2', 'struct3'}; 

%Iterate all structs names 
%Modify data elements of each struct using eval. 
for i = 1:length(struct_names) 
    sname = struct_names{i}; %Get struct name from cell array. 

    %Evaluate a string like: 'struct1.data = struct1.data + 1;' 
    eval([sname, '.data = ', sname, '.data + 1;']); 
end 
+0

_ «Использование eval неэффективно, так что не делайте его привычкой ...» _ зачем рекомендовать вредные привычки? – EBH

+0

@EBH В некоторых случаях использование eval - лучшая альтернатива. Когда даны шаблоны (не в пределах массива в первую очередь), использование eval выглядит как лучшее решение, чем создание массива структур и использование элементов массива с этого момента. Важно знать опцию «eval», но не использовать ее, когда это необязательно. – Rotem

+0

Этот вид решает проблему, но я бы не рекомендовал ее. Если возможно, следует избегать 'eval' и _if_, в коде не должно быть голых оценок.Я бы предпочел взять catenate структуру, хотя потребуется некоторое дополнительное время и память (временная память). – patrik

Смежные вопросы