结合2个MATLAB结构

时间:2019-03-15 19:10:33

标签: matlab

我想结合两个小结构,但找不到正确的解决方案。结构A和B具有相同的一列(相同的字符串值),尽管重要的是公共值不必在两者之间具有相同的顺序。为了示例,我将它们放在不同的顺序中。我想实现下面的结构C中的功能,其中两个结构的信息都组织在一起:

A(1).condition = 'con1';
A(1).y = rand(10, 1);
A(2).condition = 'con2';
A(2).y = rand(10, 1);

B(1).condition = 'con2';
B(1).z = normrnd(0,1);
B(2).condition = 'con1';
B(2).z = normrnd(0,1);

% Desired output:
C = A;
C(1).z = B(2).z;
C(2).z = B(1).z

3 个答案:

答案 0 :(得分:2)

您需要:

  1. 根据condition的值,找到一个结构数组的元素与另一个结构数组匹配的顺序。
  2. B(i)中的每个字段复制到数组A的相应元素中。我假设B中的字段多于zcondition

可以使用ismember完成第1步,该变量的第二个输出参数将索引分配到一个数组中与另一个元素匹配的数组中。我们假设B的每个元素在A中都有一个匹配的元素:

[~,I] = ismember({A.condition},{B.condition});

请注意,{A.condition}是包含所有condition字符串的单元格数组。 B(I)是结构数组B重新排序以匹配A

第2步可以像在rahnema1's answer中一样完成,我们在此概括为使用字段名循环和dynamic field names复制多个字段:

fields = fieldnames(B);
fields = setdiff(fields,'condition'); % don't copy over this field
for ii = 1:numel(fields)
   [A.(fields{ii})] = B(I).(fields{ii});
end

测试:

A(1).condition = 'con1';
A(1).y = [1,1,1];
A(2).condition = 'con2';
A(2).y = [2,2];
A(3).condition = 'con3';
A(3).y = [3,3,3];

B(1).condition = 'con2';
B(1).z = 2;
B(1).x = 'b';
B(2).condition = 'con3';
B(2).z = 3;
B(2).x = 'c';
B(3).condition = 'con1';
B(3).z = 1;
B(3).x = 'a';

[~,I] = ismember({A.condition},{B.condition});

fields = fieldnames(B);
fields = setdiff(fields,'condition'); % don't copy over this field
for ii = 1:numel(fields)
   [A.(fields{ii})] = B(I).(fields{ii});
end

这将产生以下结构A

>> A(1)

ans = 

  struct with fields:

    condition: 'con1'
            y: [1 1 1]
            x: 'a'
            z: 1

>> A(2)

ans = 

  struct with fields:

    condition: 'con2'
            y: [2 2]
            x: 'b'
            z: 2

>> A(3)

ans = 

  struct with fields:

    condition: 'con3'
            y: [3 3 3]
            x: 'c'
            z: 3

答案 1 :(得分:1)

您可以将comma separated list分配给另一个逗号分隔的列表:

C = A;
[C(2:-1:1).z] = B.z;

[C.z] = B(2:-1:1).z;

答案 2 :(得分:0)

它不优雅,但是应该可以工作:

C = A
for idx_A = 1:length(A)
    for idx_B = 1:length(B)
        if strcmp(A(idx_A).condition, B(idx_B).condition)
            C(idx_A).z = B(idx_B).z
        end
    end
end

如果需要频繁的合并操作,可以考虑使用Array.forEach()。如果您想坚持使用结构,我认为通常建议使用数组结构而不是结构数组,例如:

A.condition = {'con1', 'con2'};
A.y = [rand(10, 1), rand(10, 1)]

这使许多操作变得容易。