我想合并结构字段,以防我进行部分计算,以便稍后填充整个结构字段单元格。
将结果根据索引放入单元格中,如下所示:
for i=3:4;
results1.index{i}=i;
results1.sqr{i}=i*i;
end
for i=1;
results2.index{i}=i;
results2.sqr{i}=i*i;
end
分别给予:
results1 =
index: {[] [] [3] [4]}
sqr: {[] [] [9] [16]}
results2 =
index: {[1]}
sqr: {[1]}
是否有一种方法可以合并结果结构以获得
allresults.index={[1] [] [3] [4]}
allresults.sqr={[1] [] [9] [16]}
我可以避免重叠的结果,所以没有冲突解决或覆盖的情况下冲突的值(例如,没有单元格是空的)将是ok的。请注意,在较大的数据集中,单元格不仅限于标量,还可能包含单元格或其他类型。
您可以先编写一个小的辅助函数来合并单元格:
function R = mergeCells(A,B)
R = {};
IA = ~cellfun('isempty',A);
IB = ~cellfun('isempty',B);
R(IA) = A(IA);
R(IB) = B(IB);
end
,然后在循环中调用它来合并
字段for k = 1:numel(F),
f = F{k};
allresults.(f) = mergeCells(results1.(f), results2.(f));
end
下面是完成此操作的函数。我认为它是相当通用的,它确实处理字符串,但没有假设冲突。如果struct
具有不同的字段名或不同的字段数,则会失败。我不能告诉你任何关于性能的事情,也不能告诉你是否有更好的方法来做到这一点。
function T = structCat(re1,re2)
F=fieldnames(re1);
for i=1:length(F) %// Do one field name at a time
t1=re1.(F{i}); %// These are the individual cell arrays we are combining
t2=re2.(F{i});
if length(t2)>length(t1)
%// This loop just makes t1 be the longest cell array, it's a bit messy though
t1a=t1;
t1=t2;
t2=t1a;
end
T.(F{i})=t1; %// Now we know t1 is longer, set the new array to t1 initially
for j=1:length(t2) %// Do each element of t2 individually
if ~exist(T.(F{i}){j},'var') %// see if there is an element of t2 to insert into T
T.(F{i}){j}=t2{j}; %// if there is, insert it!
end
end
end
end
用法,例如:
for i=3:4;
re1.index{i}=i;
re1.index2{i}=i^2;
re1.strings{i}='dafsd';
re1.mat{i}=[i;2*i;3*i];
end
for i=1;
re2.index{i}=i;
re2.index2{i}=i^2;
re2.strings{i}='hmmm';
re2.mat{i}=[i;2*i;3*i].^2;
end
T=structCat(re1,re2)
结果是
T =
index: {[1] [] [3] [4]}
index2: {[1] [] [9] [16]}
strings: {'hmmm' [] 'dafsd' 'dafsd'}
mat: {[3x1 double] [] [3x1 double] [3x1 double]}
你也应该在Matlab文件交换中查看这个问题和这个条目,尽管我认为它们做的事情略有不同。
两个答案都有效。所以我把莫森的简单和大卫的一步法结合起来:
function C = structCat2(A,B)
F=fieldnames(A);
for k = 1:numel(F),
f = F{k};
IA = ~cellfun('isempty',A.(f));
IB = ~cellfun('isempty',B.(f));
C.(f)(IA) = A.(f)(IA);
C.(f)(IB) = B.(f)(IB);
end