在MATLAB中,有哪些有效的方法可以组合两种结构?

在MATLAB中,有哪些有效的方法可以组合两种结构?,matlab,merge,structure,field,Matlab,Merge,Structure,Field,我想用不同的字段名组合两个结构 例如,从以下内容开始: A.field1 = 1; A.field2 = 'a'; B.field3 = 2; B.field4 = 'b'; 我希望: C.field1 = 1; C.field2 = 'a'; C.field3 = 2; C.field4 = 'b'; 有没有比使用“字段名”和for循环更有效的方法 编辑:假设在字段名冲突的情况下,我们优先选择C中的A,一个结构可以有另一个结构作为其成员之一。虽然这与您所要求的并不完全相同,但您可能会遇到

我想用不同的字段名组合两个结构

例如,从以下内容开始:

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

B.field3 = 2;
B.field4 = 'b';
我希望:

C.field1 = 1;
C.field2 = 'a';
C.field3 = 2;
C.field4 = 'b';
有没有比使用“字段名”和for循环更有效的方法


编辑:假设在字段名冲突的情况下,我们优先选择C中的
A

,一个结构可以有另一个结构作为其成员之一。虽然这与您所要求的并不完全相同,但您可能会遇到这样的情况:一个结构包含另一个结构,或者一个结构包含两个结构,这两个结构都包含您想要的部分信息

我不记得实际的语法了

A.field1 = 1;
A.field2 = 'a';
A.field3 = struct B;
要访问: A.field3.field4

或者类似的东西

或者可以让结构C同时保存A和B:

C.A = struct A;
C.B = struct B;
有了访问权限

C.A.field1;
C.A.field2;
C.B.field3;
C.B.field4;
希望这有帮助

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


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

在没有冲突的情况下,您可以这样做

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{:});

通过假设没有冲突,并在调用
struct
时使用try/catch来优雅地降级为冲突处理案例,您可能能够生成一个混合解决方案。

我不认为您可以在没有循环的情况下很好地处理冲突,也不认为您需要避免冲突。(尽管我认为效率可能是一个涉及许多领域的问题……)

我使用了几年前我编写的一个函数,名为
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
):

以及一些测试样本:

>> 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
我找到了一个不错的工作

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

以下是它的工作原理:

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

s = catstruct(a,b)
将给予

s = 

    f1: 1
    f2: 3
    f3: 4

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


官方解决方案由Loren舒尔发布于上,并由和演示。但是,如果您有信号处理工具箱,一个简单的未记录函数已经可以执行此操作-
setstructfields

帮助设置结构字段

setstructfields使用另一个结构设置结构的字段
setstructfields(STRUCTIN,NEWFIELDS)使用
另一个结构是NEWFIELDS。如果STRUCTIN中存在字段
但在NEWFIELDS,它们不会被改变。
在内部,它使用
fieldnames
作为循环,因此它是一个方便的函数,对于本身是结构的字段,它具有错误检查和递归功能

示例

“原始”结构:

第二个结构包含
'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'
已更新。添加了字段
“形状”
。“颜色”字段保持不变


注意:由于该函数没有文档记录,它可能会随时更改或删除。

谢谢,这正是我需要的行为。我想知道为什么它不是标准库的一部分
第一个解决方案可以通过
cell2struct
转换为一行程序。我不知道它的性能如何。
% struct with fields 'count' and 'shape'
s2 = struct('count',4,'shape','round')

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