Adding a field to an empty struct

☆樱花仙子☆ 提交于 2019-12-10 17:21:40

问题


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!


回答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



回答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.




回答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



回答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


来源:https://stackoverflow.com/questions/14830370/adding-a-field-to-an-empty-struct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!