Можно ли получить доступ к значениям этой структуры / изменить их без использования цикла for?
Вот мой начальный массив структуры:
A(1).B.C = 'a';
A(2).B.C = 'b';
A(3).B.C = 'a';
A(4).B.C = 'a';
Я хочу изменить значения поля C
на основе значений Values
и индексы IndexingArray
:
Values = {'a', 'b'};
IndexingArray = [1 1 0 1];
Итак, мой новый массив структуры будет:
A(1).B.C = 'b';
A(2).B.C = 'b';
A(3).B.C = 'a';
A(4).B.C = 'b';
Есть ли способ сделать это без использования цикла for?
2 ответа
Вы можете сделать это без использования циклов deal
и синтаксис списка через запятую, но читать его может быть немного сложнее:
% Initialize A:
A(1).B.C = 'a';
A(2).B.C = 'b';
A(3).B.C = 'a';
A(4).B.C = 'a';
Values = {'a', 'b'};
IndexingArray = [1 1 0 1];
temp = [A.B]; % Structure array containing B substructures
[temp.C] = deal(Values{IndexingArray+1}); % Set field C of each structure element
temp = num2cell(temp); % Convert to a cell array of 1-by-1 structures
[A.B] = deal(temp{:}); % Update B substructures
А в более новых версиях MATLAB вы можете опустить deal
в целом:
temp = [A.B];
[temp.C] = Values{IndexingArray+1};
temp = num2cell(temp);
[A.B] = temp{:};
Это должно позволить вам обновить B
а также C
поля, не влияя на любые другие поля, которые могут существовать в вашей более сложной структуре.
Вместо изменения значения проще перестроить массив структур.
Получить значение по
IndexingArray
:val = Values(IndexingArray+1);
Построить массив структур, используя
cell2struct
и преобразовать в массив ячеек, используяnum2cell
:T = num2cell(cell2struct(val, {'C'}, 1));
Перерабатывать
T
результат для массива структур, использующихcell2struct
:A = cell2struct(T', {'B'}, 1);
Вот пример кода для создания A:
Values = {'a', 'b'};
IndexingArray = [1 1 0 1];
val = Values(IndexingArray+1);
T = num2cell(cell2struct(val, {'C'}, 1));
A = cell2struct(T', {'B'}, 1);
Построение А в одной строке кода:
A = cell2struct((num2cell(cell2struct(Values(IndexingArray+1), {'C'}, 1)))', {'B'}, 1);
Результат (для тестирования):
>> A(1).B.C
ans =
b
>> A(2).B.C
ans =
b
>> A(3).B.C
ans =
a
>> A(4).B.C
ans =
b
Решение с использованием arrayfun
:
val = Values(IndexingArray+1);
A = arrayfun(@(x) struct('B', struct('C', val{x})), 1:4)
Обновить конкретные элементы A:
В случае, если вам нужно обновить определенные элементы, вместо того, чтобы перезаписать A
Вы можете подать заявку arrayfun
выборочно, к индексам, вы знаете, что нужно обновить.
Пример:
Предполагать A
длина составляет 6 элементов, и вам нужно обновить первые 4, вы можете использовать следующий код:
A(1:4) = arrayfun(@(x) struct('B', struct('C', val{x})), 1:4);
Предположим, вы знаете, что вам нужно только обновить A(1)
а также A(4)
Вы можете использовать следующий пример:
A(1).B.C = 'a';
A(2).B.C = 'b';
A(3).B.C = 'a';
A(4).B.C = 'a';
A(5).B.C = 'c';
A(6).B.C = 'd';
Values = {'a', 'b'};
IndexingArray = [1 1 0 1];
val = Values(IndexingArray+1);
%List of indices of A to update
indices = [1, 4];
A(indices) = arrayfun(@(x) struct('B', struct('C', val{x})), indices);