这是我的初始结构数组:
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循环的情况下完成?
答案 0 :(得分:3)
你 可以使用deal
和comma separated list语法进行循环,但看起来有点难以理解:
% 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
字段,而不会影响更复杂结构中可能存在的任何其他字段。
答案 1 :(得分:1)
不是更改值,而是重建结构数组更简单。
按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:
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);