在MATLAB中结合两种结构的有效方法有哪些?
时间:2020-03-05 18:46:11 来源:igfitidea点击:
我想结合两个具有不同字段名称的结构。
例如,从以下开始:
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
。
解决方案
回答
在C语言中,一个结构可以拥有另一个结构作为其成员之一。尽管这与我们要求的不完全相同,但是我们可能会遇到以下情况:一个结构包含另一个结构,或者一个结构包含两个结构,这两个结构都包含我们想要的部分信息。
psuedocode:我不记得实际的语法。
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{:});
这是相当有效的。但是,重复字段名上的"结构"错误,并使用"唯一"进行预检查会导致性能下降,从而使循环更好。但是,结果如下所示:
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):
% 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