


CATSTRUCT Concatenate or merge structures with different fieldnames
X = CATSTRUCT(S1,S2,S3,...) merges the structures S1, S2, S3 ...
into one new structure X. X contains all fields present in the various
structures. An example:
A.name = 'Me' ;
B.income = 99999 ;
X = catstruct(A,B)
% -> X.name = 'Me' ;
% X.income = 99999 ;
If a fieldname is not unique among structures (i.e., a fieldname is
present in more than one structure), only the value from the last
structure with this field is used. In this case, the fields are
alphabetically sorted. A warning is issued as well. An axample:
S1.name = 'Me' ;
S2.age = 20 ; S3.age = 30 ; S4.age = 40 ;
S5.honest = false ;
Y = catstruct(S1,S2,S3,S4,S5) % use value from S4
The inputs can be array of structures. All structures should have the
same size. An example:
C(1).bb = 1 ; C(2).bb = 2 ;
D(1).aa = 3 ; D(2).aa = 4 ;
CD = catstruct(C,D) % CD is a 1x2 structure array with fields bb and aa
The last input can be the string 'sorted'. In this case,
CATSTRUCT(S1,S2, ..., 'sorted') will sort the fieldnames alphabetically.
To sort the fieldnames of a structure A, you could use
CATSTRUCT(A,'sorted') but I recommend ORDERFIELDS for doing that.
When there is nothing to concatenate, the result will be an empty
struct (0x0 struct array with no fields).
NOTE: To concatenate similar arrays of structs, you can use simple
concatenation:
A = dir('*.mat') ; B = dir('*.m') ; C = [A ; B] ;
See also CAT, STRUCT, FIELDNAMES, STRUCT2CELL, ORDERFIELDS

0001 function A = catstruct(varargin) 0002 % CATSTRUCT Concatenate or merge structures with different fieldnames 0003 % X = CATSTRUCT(S1,S2,S3,...) merges the structures S1, S2, S3 ... 0004 % into one new structure X. X contains all fields present in the various 0005 % structures. An example: 0006 % 0007 % A.name = 'Me' ; 0008 % B.income = 99999 ; 0009 % X = catstruct(A,B) 0010 % % -> X.name = 'Me' ; 0011 % % X.income = 99999 ; 0012 % 0013 % If a fieldname is not unique among structures (i.e., a fieldname is 0014 % present in more than one structure), only the value from the last 0015 % structure with this field is used. In this case, the fields are 0016 % alphabetically sorted. A warning is issued as well. An axample: 0017 % 0018 % S1.name = 'Me' ; 0019 % S2.age = 20 ; S3.age = 30 ; S4.age = 40 ; 0020 % S5.honest = false ; 0021 % Y = catstruct(S1,S2,S3,S4,S5) % use value from S4 0022 % 0023 % The inputs can be array of structures. All structures should have the 0024 % same size. An example: 0025 % 0026 % C(1).bb = 1 ; C(2).bb = 2 ; 0027 % D(1).aa = 3 ; D(2).aa = 4 ; 0028 % CD = catstruct(C,D) % CD is a 1x2 structure array with fields bb and aa 0029 % 0030 % The last input can be the string 'sorted'. In this case, 0031 % CATSTRUCT(S1,S2, ..., 'sorted') will sort the fieldnames alphabetically. 0032 % To sort the fieldnames of a structure A, you could use 0033 % CATSTRUCT(A,'sorted') but I recommend ORDERFIELDS for doing that. 0034 % 0035 % When there is nothing to concatenate, the result will be an empty 0036 % struct (0x0 struct array with no fields). 0037 % 0038 % NOTE: To concatenate similar arrays of structs, you can use simple 0039 % concatenation: 0040 % A = dir('*.mat') ; B = dir('*.m') ; C = [A ; B] ; 0041 % 0042 % See also CAT, STRUCT, FIELDNAMES, STRUCT2CELL, ORDERFIELDS 0043 0044 % for Matlab R13 and up 0045 % version 3.0 (mar 2013) 0046 % (c) Jos van der Geest 0047 % email: jos@jasen.nl 0048 0049 % History 0050 % Created in 2005 0051 % Revisions 0052 % 2.0 (sep 2007) removed bug when dealing with fields containing cell 0053 % arrays (Thanks to Rene Willemink) 0054 % 2.1 (sep 2008) added warning and error identifiers 0055 % 2.2 (oct 2008) fixed error when dealing with empty structs (Thanks to 0056 % Lars Barring) 0057 % 3.0 (mar 2013) fixed problem when the inputs were array of structures 0058 % (thanks to Tor Inge Birkenes for pointing this out). 0059 % Rephrased the help section as well. 0060 0061 error(nargchk(1,Inf,nargin)) ; 0062 N = nargin ; 0063 0064 if ~isstruct(varargin{end}), 0065 if isequal(varargin{end},'sorted'), 0066 sorted = 1 ; 0067 N = N-1 ; 0068 error(nargchk(1,Inf,N)) ; 0069 else 0070 error('catstruct:InvalidArgument','Last argument should be a structure, or the string "sorted".') ; 0071 end 0072 else 0073 sorted = 0 ; 0074 end 0075 0076 sz0 = [] ; % used to check that all inputs have the same size 0077 0078 % used to check for a few trivial cases 0079 NonEmptyInputs = false(N,1) ; 0080 NonEmptyInputsN = 0 ; 0081 0082 % used to collect the fieldnames and the inputs 0083 FN = cell(N,1) ; 0084 VAL = cell(N,1) ; 0085 0086 % parse the inputs 0087 for ii=1:N, 0088 X = varargin{ii} ; 0089 if ~isstruct(X), 0090 error('catstruct:InvalidArgument',['Argument #' num2str(ii) ' is not a structure.']) ; 0091 end 0092 0093 if ~isempty(X), 0094 % empty structs are ignored 0095 if ii > 1 && ~isempty(sz0) 0096 if ~isequal(size(X), sz0) 0097 error('catstruct:UnequalSizes','All structures should have the same size.') ; 0098 end 0099 else 0100 sz0 = size(X) ; 0101 end 0102 NonEmptyInputsN = NonEmptyInputsN + 1 ; 0103 NonEmptyInputs(ii) = true ; 0104 FN{ii} = fieldnames(X) ; 0105 VAL{ii} = struct2cell(X) ; 0106 end 0107 end 0108 0109 if NonEmptyInputsN == 0 0110 % all structures were empty 0111 A = struct([]) ; 0112 elseif NonEmptyInputsN == 1, 0113 % there was only one non-empty structure 0114 A = varargin{NonEmptyInputs} ; 0115 if sorted, 0116 A = orderfields(A) ; 0117 end 0118 else 0119 % there is actually something to concatenate 0120 FN = cat(1,FN{:}) ; 0121 VAL = cat(1,VAL{:}) ; 0122 FN = squeeze(FN) ; 0123 VAL = squeeze(VAL) ; 0124 [UFN,ind] = unique(FN) ; 0125 0126 if numel(UFN) ~= numel(FN), 0127 warning('catstruct:DuplicatesFound','Fieldnames are not unique between structures.') ; 0128 sorted = 1 ; 0129 end 0130 0131 if sorted, 0132 VAL = VAL(ind,:) ; 0133 FN = FN(ind,:) ; 0134 end 0135 0136 A = cell2struct(VAL, FN); 0137 A = reshape(A, sz0) ; % reshape into original format 0138 end 0139 0140 0141