在MATLAB中组合两个结构有哪些有效的方法?

matlab merge structure field

17753 观看

5回复

536 作者的声誉

我想结合两个具有不同字段名称的结构。

例如,从以下开始:

A.field1 = 1;
A.field2 = 'a';

B.field3 = 2;
B.field4 = 'b';

我想拥有:

C.field1 = 1;
C.field2 = 'a';
C.field3 = 2;
C.field4 = 'b';

有没有比使用“fieldnames”和for循环更有效的方法?

编辑:我们假设在字段名称冲突的情况下,我们优先考虑A

作者: KennyMorton 的来源 发布者: 2008 年 9 月 2 日

回应 (5)


2

4678 作者的声誉

在C中,struct可以将另一个struct作为其成员之一。虽然这与你提出的问题并不完全相同,但你最终可能会遇到一个结构包含另一个结构的情况,或者一个结构包含两个结构,这两个结构都包含你想要的信息的一部分。

psuedocode:我不记得实际的语法。

A.field1 = 1;
A.field2 = 'a';
A.field3 = struct B;

访问:A.field3.field4;

或类似的东西。

或者你可以让struct C同时拥有A和B:

C.A = struct A;
C.B = struct B;

有访问然后类似的东西

C.A.field1;
C.A.field2;
C.B.field3;
C.B.field4;

希望这可以帮助!

编辑:这两种解决方案都避免了命名冲突。

另外,我没有看到你的matlab标签。按照惯例,您应该编辑问题以包含该信息。

作者: pbh101 发布者: 02.09.2008 12:43

18

7356 作者的声誉

决定

没有碰撞,你可以做到

M = [fieldnames(A)' fieldnames(B)'; struct2cell(A)' struct2cell(B)'];
C=struct(M{:});

而且效率相当高。但是,struct重复字段名称出错,并使用unique杀死性能预先检查它们,以确保循环更好。但这就是它的样子:

M = [fieldnames(A)' fieldnames(B)'; struct2cell(A)' struct2cell(B)'];

[tmp, rows] = unique(M(1,:), 'last');
M=M(:, rows);

C=struct(M{:});

您可以通过假设没有冲突并在调用周围使用try / catch struct来优雅地降级到冲突处理案例来创建混合解决方案。

作者: SCFrench 发布者: 02.09.2008 02:36

4

110305 作者的声誉

我认为你不能很好地处理冲突,也不认为你需要避免冲突。(虽然我认为效率可能是许多领域的问题......)

我使用了几年前写的函数setdefaults.m,它将一个结构与另一个结构的值结合起来,在冲突的情况下,一个结构优先于另一个结构。

% SETDEFAULTS sets the default structure values 
%    SOUT = SETDEFAULTS(S, SDEF) reproduces in S 
%    all the structure fields, and their values,  that exist in 
%    SDEF that do not exist in S. 
%    SOUT = SETDEFAULTS(S, SDEF, OVERRIDE) does
%    the same function as above, but if OVERRIDE is 1,
%    it copies all fields of SDEF to SOUT.

function sout = setdefaults(s,sdef,override)
if (not(exist('override','var')))
    override = 0;
end

sout = s;
for f = fieldnames(sdef)'
    cf = char(f);
    if (override | not(isfield(sout,cf)))
        sout = setfield(sout,cf,getfield(sdef,cf));
    end
end

现在我考虑一下,我很确定“覆盖”输入是不必要的(你可以只是切换输入的顺序)虽然我不是100%肯定...所以这里是一个更简单的重写(setdefaults2.m):

% SETDEFAULTS2 sets the default structure values 
%    SOUT = SETDEFAULTS(S, SDEF) reproduces in S 
%    all the structure fields, and their values,  that exist in 
%    SDEF that do not exist in S. 

function sout = setdefaults2(s,sdef)
sout = sdef;
for f = fieldnames(s)'
    sout = setfield(sout,f{1},getfield(s,f{1}));
end

和一些样品来测试它:

>> S1 = struct('a',1,'b',2,'c',3);
>> S2 = struct('b',4,'c',5,'d',6);
>> setdefaults2(S1,S2)

ans = 

    b: 2
    c: 3
    d: 6
    a: 1

>> setdefaults2(S2,S1)

ans = 

    a: 1
    b: 4
    c: 5
    d: 6
作者: Jason S 发布者: 10.12.2008 07:58

5

16939 作者的声誉

在File Exchange上找到了一个很好的解决方案:catstruct

如果不测试性能,我可以说它完全符合我的要求。它当然可以处理重复的字段。

下面是它的工作原理:

a.f1 = 1;
a.f2 = 2;
b.f2 = 3;
b.f4 = 4;

s = catstruct(a,b)

会给

s = 

    f1: 1
    f2: 3
    f3: 4
作者: Dennis Jaheruddin 发布者: 19.09.2013 11:45

8

28521 作者的声誉

简答:( setstructfields如果您有信号处理工具箱)。


官方解决方案由Loren Shure在她的MathWorks博客上发布,并由SCFrench在这里Eitan T对不同问题的回答进行了演示。但是,如果你有信号处理工具箱,一个简单的未记录的函数已经这样做了 - setstructfields

help setstructfields

 setstructfields Set fields of a structure using another structure
    setstructfields(STRUCTIN, NEWFIELDS) Set fields of STRUCTIN using
    another structure NEWFIELDS fields.  If fields exist in STRUCTIN
    but not in NEWFIELDS, they will not be changed.

在内部它使用fieldnamesfor循环,因此它是一个便利函数,具有错误检查和自身结构的字段的递归。

“原始”结构:

% struct with fields 'color' and 'count'
s = struct('color','orange','count',2)

s = 
    color: 'orange'
    count: 2

包含新值的第二个结构'count',以及一个新字段'shape'

% struct with fields 'count' and 'shape'
s2 = struct('count',4,'shape','round')

s2 = 
    count: 4
    shape: 'round'

致电setstructfields

>> s = setstructfields(s,s2)
s = 
    color: 'orange'
    count: 4
    shape: 'round'

该字段'count'更新。该字段'shape'添加。该领域'color' 保持不变

注意:由于该功能未记录,因此可能随时更改或删除。

作者: chappjc 发布者: 20.05.2014 06:45
32x32