I load multiple structs from separate files and want to collect them in one struct of arrays. Since the struct has a lot of fields, I'm looping over its fieldnames
, at the moment like this:
for fnc = fieldnames(result)'
fn = fnc{:}
results.(fn) = [results.(fn) result.(fn)];
end
This works fine for scalar fields, howeve开发者_如何学运维r some fields are vectors or matrices and should therefore be stored as matrices or 3rd rank tensors respectively. I can use some if length
and if ndims
to treat these cases individually, but
is there a more general way to use the next higher dimension for appending?
To append along the last dimension, you can use the commands CAT and NDIMS:
%# find the number of dimensions
nd = ndims(results.(fn));
%# catenate along the last dimension
results.(fn) = cat(nd,results.(fn), newResult.(fn));
Note that building arrays by catenation can be fairly slow if there are lots of iterations, though in your case, pre-allocating will be somewhat involved, so I'd only do it if it's really necessary. Also, using variables results
as well as result
is setting yourself up for hard-to find bugs.
This is my current solution with which I'm not all too happy:
% merge current result fields into results
resFields = fieldnames(result);
for jf = 1:numel(resFields)
rf = resFields{jf};
resf = result.(rf);
nd = ndims(resf);
rt = r.(rf);
if nd==2 && min(size(result.(rf)))==1 % scalar or vector
rt = [ rt; result.(rf) ];
elseif nd == 2 % true matrix, so append to 3rd rank tensor
rt(:,:,end+1) = result.(rf);
elseif ndims(result.(rf)) == 3 % 3rd rank tensor, append to 4th rank tensor
rt(:,:,:,end+1) = result.(rf);
else
warning(['Too many dimensions for result field ' rf ': ' num2str(ndims(result.(rf)))]);
rt(end+1) = result.(rf);
end;
results.(rf) = rt;
end;
end;
I could of course manually extend this to any tensor rank up to a sensible degree, but this is very redundant and ugly, so I'd really appreciate a better looking solution that works in the general case as well.
精彩评论