Обновление одного поля в каждом элементе массива структуры Matlab - PullRequest
19 голосов
/ 16 февраля 2012

Предположим, у меня есть массив 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{:});

Есть идеи?Благодаря.

Ответы [ 3 ]

11 голосов
/ 16 февраля 2012

Просто примечание, deal там не обязательно:

[arr.val] = newVals{:}; % achieves the same as deal(newVals{:})

Единственный другой способ, которым я знаю, как это сделать (без цикла foor), это использовать 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){:}).

1 голос
/ 16 февраля 2012

Все поля в этой структуре скалярные или имеют одинаковый размер?Если это так, то идиоматический способ сделать это в Matlab состоит в том, чтобы перестроить вашу структуру в скалярную структуру с массивами в каждом из ее полей, вместо массива структур со скалярными значениями в полях.Затем вы можете выполнять векторизованные операции над полями, например arr.val = arr.val + 3;.Посмотрите, можете ли вы изменить ваши данные.Делать это таким образом гораздо эффективнее как по времени, так и по памяти;Вероятно, поэтому Matlab не предоставляет удобный синтаксис для работы над полями массивов структур.

0 голосов
/ 27 января 2017

Если массив структуры, который вы пытаетесь установить, представляет собой набор графических объектов (маркеры линий, маркеры фигур, маркеры осей и т. Д.), То вам нужно использовать функцию 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
...