Code covered by the BSD License  

Highlights from

4.7 | 22 ratings Rate this file 88 Downloads (last 30 days) File Size: 4.95 KB File ID: #7842



Jos (10584) (view profile)


13 Jun 2005 (Updated )

Concatenate/merge structures (v4.1, feb 2015).

| Watch this File

File Information

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: = 'Me' ;
      B.income = 99999 ;
      X = catstruct(A,B)
      % -> = '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: = '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).
To concatenate similar arrays of structs, you can use simple concatenation:
      A = dir('*.mat') ; B = dir('*.m') ; C = [A ; B] ;
Latest version: 4.0 (dec 2013)


This file inspired Structable and Lynx Matlab Toolbox.

MATLAB release MATLAB 8.3 (R2014a)
MATLAB Search Path
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (31)
05 Jan 2015 Brad Stiritz

Great utility, thanks for providing this. Please be aware that your current version 4.0 generates two warnings in R2014b that nargchk() will be removed in a future MATLAB version.

13 Aug 2014 Christian  
13 May 2014 maysam

maysam (view profile)

01 May 2014 Colin

Colin (view profile)

17 Mar 2014 Krzysztof

N = nargin ;

sorted = varargin { end };
if ischar(sorted)
assert (all (sorted == 'sorted'))
sorted = 1 ;
N = N-1 ;
sorted = 0 ;

11 Mar 2013 Jos (10584)

Jos (10584) (view profile)

Thanks Christophe for pointing out the changed behavior of unique! I will fix this soon.

Comment only
09 Mar 2013 Christophe

One solution to restore compatibility across MATLAB version would be to substitute line 124:
[UFN,ind] = unique(FN) ;
if verLessThan('matlab','8.1')
[UFN,ind] = unique(FN) ;
[UFN,ind] = unique(FN,'legacy') ;

Comment only
08 Mar 2013 Christophe

This is a very useful function!

Unfortunately, it seems that the release of MATLAB 2013a breaks its behavior. They have changed the behavior of the function unique and now when I type


I get

A: 1

Comment only
08 Mar 2013 Christophe  
06 Mar 2013 Jos (10584)

Jos (10584) (view profile)

@Tor Inge Birkenes
I see your problem! An update is being submitted ...

Comment only
01 Mar 2013 Tor Inge Birkenes

If its inteded it is of course all right, but it feels inconsistent to me.
I care about this because I am using structs to store configuration parameters and use your function to merge standard and user defined values. In this case it is expected to have duplicate fields. As you point out this is outside the intended use of the function, but it still works great.

In case my explanation of the problem was insufficient i include concrete example this time:

% Defining struct arrays = 'fred';
s1.age = 42;
s1(2).name = 'alice';
s1(2).age = 29;
s2.height = 170;
s2(2).height = 160;
% Concentrate
% A is a 1x2 struct array
% with fields: name, age, height

% Add duplicate field
s1(1).height= '142';
s1(2).height = '195';
% Concentrate
% A2 is a struct with fields:
% name, age, height

I is the dimension difference (1x2 vs 1x1) that i find inconsistent, and I did not expect based on the warning "Warning: Duplicate fieldnames found. Last value is used and fields are sorted". I would expect an 1x2 array where the field values from s2 were used when there are conflict, as the function does with the first field in the structure.

Comment only
28 Feb 2013 Jos (10584)

Jos (10584) (view profile)

@Tor Inge Birkenes
This behaviour is intended. CATSTRUCT merges separate structures containing different(!) field names into 1. For instance, it works perfectly for the initial example given in Loren's blog.

Comment only
28 Feb 2013 Tor Inge Birkenes

Great function!

I found a bug when concentrating struct arrays with common fields.
Then only the first struct was concentrated, the rest was discarded.
For an example add height-field to s1 in the example here, and concentrate:

I fixed it by changing
VAL = VAL(ind) ;
FN = FN(ind) ;
VAL = VAL(ind,:,:) ;
FN = FN(ind,:,:) ;
at line 88-89. Seems to work nicely.

21 Feb 2012 Wintersprite

simple to use, but what I really wanted to do was to gather up 5 structures and put them into one structure variable, whereas this script flattened my existing structures.

17 Dec 2011 Wouter

Wouter (view profile)

I also needed to concatenate arrays and cells at the leaf nodes in the case when the fieldnames match. This can be done by slightly adjusting the code as:
if numel(UFN) ~= numel(FN),
warning('catstruct:DuplicatesFound','Duplicate fieldnames found. Fields are merged and sorted.') ;
Nd = numel(unique(j));
for i=1:Nd
idx = find(j==unique(j(i)));
[nr,nc] = cellfun(@size, VAL(idx));
% comment if fields are not required to be equal in size:
if diff(nr) || diff(nc);error(['Duplicate field ' FN{idx(1)} ' does not have the same size for all structures.']);end
[p,rcm] = min([nc(1) nr(1) 2]);
% concatenate rows as rows, colums as colomns and matrices along 2nd dimension.
VAL{idx(end)} = cat(min(rcm,2),VAL{idx});
sorted = 1;

Comment only
17 Dec 2011 Wouter

Wouter (view profile)

14 Feb 2011 grega

grega (view profile)

10 Feb 2011 K E

K E (view profile)

Should be standard in Matlab

17 Jul 2009 Scott Otterson

This works well. I agree with Jeremy that recursive concatenation would be an advantage. It would also be useful to concatenate arrays and cells at the leaf nodes in the case when the fieldnames match (I've had to do this many times).

But it works for what I'm doing at the moment. Thanks!

08 Apr 2009 Gabriel Akira Schreiber

great work, may the sun always shine on you.

22 Jan 2009 Jeremy

Jeremy (view profile)

Nice work, just one comment:
I just noticed that when merging two structures, the fact that any dissimilar fields in the FIRST level are merged, but dissimilarities in subsequent levels are lost: e.g.

s1.a = 1;
s1.b = 2;

s2.a = 101;

s3 = catstruct(s1,s2) gives s3.a = 101, s3.b = 2.

s1.A.a = 1;
s1.A.b = 2;

s2.A.a = 101;

gives s3.A = a : 101.
i.e. we lose field b. I kind of understand the logic, i.e. that it is now field A that is being overwritten by a new field A, so that a depth=1 merge has occurred, but for anyone looking to do a true merge-style operation, this means needing to loop though each level... any plans to change this?

11 Dec 2008 Daniel

Daniel (view profile)

29 Sep 2008 Jos (the author)

To Benny. Catstruct does work on structures with non-numeric fields (see the example). You're after simple concatenation, for which you do not need catstruct at all ...

a = dir('*.mat')
b = dir('*.txt')
c = [a ; b] ;

Comment only
29 Sep 2008 Benny .

Good job. It would be very usefull if it also worked on general structures, not only those containing numerical matrices only, e.g.

a = dir('*.txt');
b = dir('*.mat');
c = catstruct(a,b);

04 Aug 2008 Piotr .

Very useful function!

28 May 2008 Maziar Hashemi-Nezhad

Perfect basic program

21 Feb 2008 Hoi Wong

Cool program. I can't imagine why MATLAB wouldn't have something like this built-in, but you filled the gap!

21 Sep 2007 Jos (the author)

new version 2.0 (sep 2007). A bug was removed which ocured when fields contained cell arrays.

Comment only
04 May 2007 Jingzhao Ou

A very useful script!

16 Apr 2007 Nadaraja Pillai

Hi ,
It is possible to concates the structure simply using collon... For example...


It will do it...

28 Oct 2006 Paolo de Leva

This function is a must for people using structures. I wonder why MATLAB doesn't allow (as far as I know) structure concatenation using the [S1, S2] syntax, when the two structures have different fields. The builtin function STRUCT can't add fields to an existing structure...

21 Jun 2006

added semi-colons

24 Sep 2007

removed bug when delaing with fields containing cell arrays

24 Sep 2007

add keywords

16 Sep 2008

added identifiers

06 Mar 2013

now deals correctly with arrays of structures (thanks to Tor Inge Birkenes for pointing out this problem)

04 Dec 2013

Due to changes implemented by The Mathworks in their set functions, I had to explicitly tell unique to return the last occurrence of a value in a set ...

04 Feb 2015

changed number of input arguments check to accommodate future releases. Probably this function will no longer work anymore in older releases :-(

Contact us