Reputation: 21561
Assuming I have a struct S
of size 0x1 with the fields a
and b
, what is the most elegant way to add a field c
to it?
Usually I am able to do it like this:
S = struct('a',0,'b',0); %1x1 struct with fields a,b
S.c = 0
However, if I receive an empty struct this does not work anymore:
S = struct('a',0,'b',0);
S(1) = []; % 0x1 struct with fields a,b
S.c = 0;
% A dot name structure assignment is illegal when the structure is empty.
% Use a subscript on the structure.
I have thought of two ways to deal with this, but both are quite ugly and feel like workarounds rather than solutions. (Note the possibility of a non-empty struct should also be dealt with properly).
I realize that it may be odd that I care about empty structs, but unfortunately part of the code that is not managed by me will crash if the fieldname does not exist. I have looked at help struct
, help subsasgn
and also searched for the given error message but so far I have not yet found any hints. Help is therefore much appreciated!
Upvotes: 6
Views: 21599
Reputation: 56
You can use setfield
to solve the problem.
S = struct('a', {}, 'b', {});
S = setfield(S, {}, 'c', [])
This results in
S =
0x0 struct array with fields:
a
b
c
Upvotes: 2
Reputation: 124563
Just to expand on @Shai's answer, here is a simple MEX-function you can use:
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
char *fieldname;
/* Check for proper number of input and output arguments */
if (nrhs != 2) {
mexErrMsgIdAndTxt("struct:nrhs", "Two inputs required.");
} else if (nlhs > 1) {
mexErrMsgIdAndTxt("struct:nlhs", "Too many output arguments.");
} else if (!mxIsStruct(prhs[0])) {
mexErrMsgIdAndTxt("struct:wrongType", "First input must be a structure.");
} else if (!mxIsChar(prhs[1]) || mxGetM(prhs[1])!=1) {
mexErrMsgIdAndTxt("struct:wrongType", "Second input must be a string.");
}
/* copy structure for output */
plhs[0] = mxDuplicateArray(prhs[0]);
/* add field to structure */
fieldname = mxArrayToString(prhs[1]);
mxAddField(plhs[0], fieldname);
mxFree(fieldname);
}
Example:
>> S = struct('a',{});
>> S = addfield(S, 'b')
S =
0x0 struct array with fields:
a
b
Upvotes: 1
Reputation: 9317
You can use deal
to solve this problem:
S = struct('a',0,'b',0);
S(1) = [];
[S(:).c] = deal(0);
This results in
S =
1x0 struct array with fields:
a
b
c
This works also for non-empty structs:
S = struct('a',0,'b',0);
[S(:).c] = deal(0);
which results in
S =
a: 0
b: 0
c: 0
Upvotes: 7
Reputation: 114966
How about
S = struct('a', {}, 'b', {}, 'c', {} );
To create an empty struct?
Another way is to use mex
file with mxAddField
as a workaround to the error you got:
A dot name structure assignment is illegal when the structure is empty.
Use a subscript on the structure.
Upvotes: 2