MATLAB Answers

How to create an empty array of structs?

1,400 views (last 30 days)
I would like to make a loop that accumulates an array of structures, such as
array=struct([]); % The docs imply that this should work
for i=1:n
st=CreateAStruct(i);
array(i)=st;
end;
But...this doesn't work, I get the error, "Subscripted assignment between dissimilar structures." on the first pass through the loop. Instead the only way I've found to do this is the following.
for i=1:n
st=CreateAStruct(i);
if i==1
array=st;
else
array(i)=st;
end;
end;
Is there a nicer way to do this?

  3 Comments

Andrei Bobrov
Andrei Bobrov on 2 Aug 2011
array=CreateAStruct(1); % The docs imply that this should work
for i=2:n
array(i)=CreateAStruct(i);
end;
Fred Sigworth
Fred Sigworth on 2 Aug 2011
Yes, exactly. But why can't I start with an empty struct and fill it in, just like I can do with an array, e.g.
vec=[];
for i=1:n
vec(i)=GetValue(i);
end;
Gustavo Delfino
Gustavo Delfino on 4 Oct 2016
Did you ever find the answer to this question?

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 2 Aug 2011
You are correct, struct() is a struct with no fields, and that is a distinct structure that is not the same as a structure with any defined fields.
Workaround:
T = arrayfun(@(K) CreateAsStruct(K), 1:n, 'UniformOutput',0);
array = horzcat(T{:});
clear T
Also, if I recall correctly, there is a MATLAB File Exchange contribution to do assignment between dissimilar structures.

  2 Comments

KAE
KAE on 19 Dec 2019
Walter, I believe you are thinking of this FEX contribution to "concatenate structs with dissimilar fieldnames by adding empty missing fields".
Walter Roberson
Walter Roberson on 19 Dec 2019
Not back in 2011 I wasn't; that contribution was 2015. :)

Sign in to comment.

More Answers (7)

Romesh
Romesh on 28 Nov 2013
If you know the fields in advance, you can create a 0x0 struct array WITH fields using the syntax
s = struct('a',{},'b',{})
which returns
s =
0x0 struct array with fields:
a
b
This lets you do things like
x.a = 1;
x.b = 1;
s(end+1) = x;
which otherwise fail with the original error message when the struct is initialised as struct([])

  2 Comments

Richard Crozier
Richard Crozier on 23 Mar 2018
This should be the accepted answer.
Walter Roberson
Walter Roberson on 26 Mar 2018
Richard, this does not satisfy the original requirement that the struct entry be the result of executing CreateAStruct with argument equal to the index.

Sign in to comment.


Philip Borghesani
Philip Borghesani on 13 Jan 2017
Actualy the simplest and fastest solution to this problem is to not attempt to create an empty struct. Run the loop backwards to allocate the full structure array on the first loop:
% do not attempt to preallocate array
for i=n:-1:1
array(i)=CreateAStruct(i);
end

  2 Comments

Stephen Cobeldick
Stephen Cobeldick on 12 Jun 2017
+1 nice and simple. Just make sure that the struct is not defined in the workspace before the loop.
Jeff Miller
Jeff Miller on 25 Jan 2018
Unfortunately this doesn't work with parfor, because its range must be increasing consecutive integers. But this seems OK:
array(n)=CreateAStruct(n);
parfor i=1:n-1
array(i) = CreateAStruct(i)
end

Sign in to comment.


Sean de Wolski
Sean de Wolski on 2 Aug 2011
st = 1:10;
for ii = 1:10
array(ii).st = st(ii);
end
You need to set the value to a field of the struct since that's how structs are indexed. You could also look into using cell arrays:
doc cell

  3 Comments

Fred Sigworth
Fred Sigworth on 2 Aug 2011
Thank you, Sean, your code works. But when I then try to assign the whole larger struct to one element of the array it gives an error:
s.a=1;
s.b=2;
array=([]);
avals=1:10;
for ii=1:10
array(ii).a=avals(ii);
array(ii)=s; % if I leave this line out it works fine.
end;
I want to be able to do this because I want to build up an array (don't know beforehand how many elements) of structs that have 20 or so fields..
From the blog pointed to by Fangjun it's beginning to look like the only way I can do what I want is by crummy code like what I showed initially.
Sean de Wolski
Sean de Wolski on 2 Aug 2011
why don't you use a cell array of structs?
Nathaniel Jones
Nathaniel Jones on 12 Jun 2017
Sean, using a cell array of structs results in the following error when attempting to assign structs as elements of the cell array:
Conversion to cell from struct is not possible.
At this point, you might want to use
cell2struct()
to convert from a cell array to an array of structs. However, Romesh's answer is a better option.

Sign in to comment.


Samuel
Samuel on 3 Dec 2013
It's easy. test(10,10) = struct; This creates an 10*10 empty structs.

  1 Comment

Walter Roberson
Walter Roberson on 11 Apr 2018
This does not satisfy the original requirement that the struct entry be the result of executing CreateAStruct with argument equal to the index.

Sign in to comment.


David Young
David Young on 21 Jan 2014
For a description of the different kinds of empty structs, and a function that allows you to create each kind easily, see my File Exchange submission emptyStruct

  0 Comments

Sign in to comment.


Francesco Onorati
Francesco Onorati on 13 Jan 2017
Edited: Francesco Onorati on 13 Jan 2017
array(n)=struct(field1, [], field2, [], ..., fieldN, []); % <-- as CreateAStruct struct
for i:n
array(i)=CreateAStruct(var1(i), var2(i));
end

  0 Comments

Sign in to comment.


Dien Nguyen
Dien Nguyen on 11 Apr 2018
Simple solution, use repmat to "repeat" "n" struct(s) as shown:
array = repmat(struct(field1, [], field2, [], ..., fieldN, []), n);

  1 Comment

Walter Roberson
Walter Roberson on 11 Apr 2018
This does not satisfy the original requirement that the struct entry be the result of executing CreateAStruct with argument equal to the index.

Sign in to comment.

Sign in to answer this question.

Products