Adding a field to an empty struct

17,947

Solution 1

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

Solution 2

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.

Solution 3

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

Solution 4

Just to expand on @Shai's answer, here is a simple MEX-function you can use:

addfield.c

#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
Share:
17,947
Dennis Jaheruddin
Author by

Dennis Jaheruddin

Helping many companies with Data Engineering, Integration and Cloud platforms. Where I work: https://www.artefact.com/ My Profile: http://jaheruddin.nl My Portfolio: https://portfolio.jaheruddin.nl

Updated on June 11, 2022

Comments

  • Dennis Jaheruddin
    Dennis Jaheruddin almost 2 years

    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).

    1. Adding something to the struct to ensure it is not empty, adding the field, and making the struct empty again
    2. Initializing a new struct with the required fieldnames, filling it with the data from the original struct, and overwriting the original struct

    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!

  • Dennis Jaheruddin
    Dennis Jaheruddin about 11 years
    I guess that I could use an if statement to see if it is indeed empty and then use this, but I still hope that there is a way to do it without the check first.
  • Dennis Jaheruddin
    Dennis Jaheruddin about 11 years
    Thanks for this nice solution. Could you perhaps explain why this works, but why [S.c] = deal(0) does not?
  • H.Muster
    H.Muster about 11 years
    Please pardon me, but actually, I do not know why this is the case.
  • Dennis Jaheruddin
    Dennis Jaheruddin almost 11 years
    Interested readers can check my follow up question where the issue is addressed: stackoverflow.com/questions/16342688/…
  • Amro
    Amro over 9 years
    @down-voter: why, care to comment? If there is a problem with the code, I'm happy to improve it... It works fine on my end!
  • Dennis Jaheruddin
    Dennis Jaheruddin almost 9 years
    Very nice, I don't see this possibility in the documentation but it seems to work the same as the accepted solution. -- Whilst looking at this, I stumbled upon one of these rare methods to crash Matlab (2012b): S = struct(); S(:)=[]; S().e=[]; S(3,3).f=[]; S().g=[];
  • nekomatic
    nekomatic over 7 years
    This code gives me Expected one output from a curly brace or dot indexing expression, but there were 0 results. (R2016b).