在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'