Подтвердить что ты не робот

Обновление одного поля в каждом элементе массива структуры 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{:});

Любые идеи? Спасибо.

4b9b3361

Ответ 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