Is it possible to concatenate structures with the same fields in to one super structure?

298 views (last 30 days)
Duncan Wright on 5 Nov 2017
Edited: Rubens Rossi on 19 Dec 2019
I have structures c and c1, each contain 55 fields with the same names.
The field dimensions differ slightly in the x domain (ie):
c.E: [68×120 single]
c.N_z_cross: [68×120 single]
c.N_z_long: [68×120 single]
and
c1.E: [84×120 single]
c1.N_z_cross: [84×120 single]
c1.N_z_long: [84×120 single]
ideally I would like to create a structure that contains both continually (ie)
full_data.E: [152×120 single]
full_data.N_z_cross: [152×120 single]
full_data.N_z_long: [152×120 single]
Is there anyway to do this without manually concatenating each variable?
Stephen on 5 Nov 2017
"Is it possible to concatenate structures": yes, it is certainly possible to concatenate structures together:
[struct1,struct2]
will concatenate two structures together. But what you describe in the body of your question is how to to concatenate structure fields together, not the structures themselves. Both of these things are possible, but require very different code.

Stephen on 5 Nov 2017
Edited: Stephen on 5 Nov 2017
>> S.data = 1;
>> S.year = 2017;
>> T.data = 2;
>> T.year = 1988;
>> Z = cell2struct(cellfun(@vertcat,struct2cell(S),struct2cell(T),'uni',0),fieldnames(S),1);
>> Z.data
ans =
1
2
>> Z.year
ans =
2017
1988
It would be perfect if structfun accepted multiple input structures, but sadly it only works on one input struct :(
Stephen on 24 Aug 2018
Note that this concept assumes that the fields are in the same order. If they are not, then use orderfields first, or use Jan's solution which relies only on the fields' names (and not their order).

Jan on 5 Nov 2017
Edited: Stephen on 2 Oct 2019
Or with a loop:
function S = CatStructFields(S, T, dim)
fields = fieldnames(S);
for k = 1:numel(fields)
aField = fields{k}; % EDIT: changed to {}
S.(aField) = cat(dim, S.(aField), T.(aField));
end
Then:
full_data = CatStructFields(c, c1, 1)
Stephen on 2 Oct 2019
@Murat Aydin: the error is easy to indentify: fieldnames returns a cell array of character vectors, but the dynamic fieldname syntax requires a character vector. So you just need to use the correct indexing to get the character vector out of the cell array:
aField = fields{k};

Ba Mo on 24 Jul 2019
Edited: Ba Mo on 24 Jul 2019
my_struct_fields = fieldnames(my_struct1);
super_struct=arrayfun(@(i) [my_struct1.(my_struct_fields{i});my_struct2.(my_struct_fields {i})],[1:numel(my_struct_fields)]','un',0);
my_dirty_trick = [my_struct_fields,super_struct]';
final_struct = struct(my_dirty_trick{:});
Thank you for officially accepting my answer

Rubens Rossi on 19 Dec 2019
Edited: Rubens Rossi on 19 Dec 2019
Thank you for the solution. I modified CatStructFields to handle my structures, which rows are 'channels'.
% Important: field position can be different between the two structures,
% but not the row position (e.g. channels), which do not have names.
S=varargin{1};
for idxV = 1:length(varargin)-1
T=varargin{idxV+1};
for k = 1:numel(F)
for h = 1:length(S)
S(h).(F{k}) = cat(dim,S(h).(F{k}),T(h).(F{k}));
end
end
end