Обновление одного поля в каждом элементе массива структуры Matlab
Предположим, что у меня есть массив struct arr
, где каждый элемент имеет кучу полей, включая один, называемый val
. Я хотел бы увеличивать каждое поле элемента val
на некоторую константу, например:
for i = 1:length(arr)
arr(i).val = arr(i).val + 3;
end
Это очевидно работает, но я чувствую, что должен быть способ сделать это только в одной строке кода (и нет для цикла). Лучшее, что я придумал, это две строки и требует временную переменную:
newVals = num2cell([arr.val] + 3);
[arr.val] = deal(newVals{:});
Любые идеи? Спасибо.
Ответы
Ответ 1
Просто примечание, deal
там не нужно:
[arr.val] = newVals{:}; % achieves the same as deal(newVals{:})
Единственный другой способ, которым я знаю, как это сделать (без петли) - использовать arrayfun
для итерации по каждой структуре массива:
% make a struct array
arr = [ struct('val',0,'id',1), struct('val',0,'id',2), struct('val',0,'id',3) ]
% some attempts
[arr.val]=arr.val; % fine
[arr.val]=arr.val+3; % NOT fine :(
% works !
arr2 = arrayfun(@(s) setfield(s,'val',s.val+3),arr)
Эта последняя команда перебирает каждую структуру в arr
и возвращает новую, где s.val
установлено значение s.val=3
.
Я думаю, что это на самом деле менее эффективно, чем предыдущий двухстрочный и цикл for, потому что он возвращает копию arr
в отличие от работы на месте.
(Это позор Matlab не поддерживает многоуровневое индексирование, например [arr.val]=num2cell([arr.val]+3){:}
).
Ответ 2
Являются ли все поля в этом структурном скалярном или одинаковом размере? Если это так, то идиоматический способ Matlab для этого состоит в том, чтобы перестроить вашу структуру как скалярную структуру с массивами в каждом из своих полей, а не массив структур со скалярными значениями в полях. Затем вы можете выполнять векторизованные операции над полями, например arr.val = arr.val + 3;
. Посмотрите, можете ли вы изменить порядок данных. Выполнение этого способа намного эффективнее как во времени, так и в памяти; вероятно, почему Matlab не обеспечивает удобный синтаксис для работы над полями массивов структур.
Ответ 3
если массив структур, который вы пытаетесь установить, представляет собой набор графических объектов (ручки строк, фигурные ручки, ручки осей и т.д.), тогда вам нужно использовать функцию set
:
x = (1:10)';
Y = rand(10,5);
l = plot(x,Y,'-k'); % returns an array of line handles in l
set(l,'Color','r'); % sets the property 'Color' for all the five lines in l