将字段添加到空结构

时间:2013-02-12 10:29:12

标签: matlab struct variable-assignment

假设我有一个大小为0x1且结构为Sa的结构b,那么向其添加字段c的最优雅方式是什么?< / p>

通常我能够这样做:

S = struct('a',0,'b',0); %1x1 struct with fields a,b
S.c = 0

但是,如果我收到一个空结构,那么它就不再起作用了:

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.

我已经想过两种方法来解决这个问题,但两者都非常难看并且感觉像解决方案而不是解决方案。 (注意,非空结构的可能性也应该正确处理)。

  1. 向结构中添加内容以确保它不为空,添加字段,并使结构再次为空
  2. 使用必需的字段名初始化新结构,使用原始结构中的数据填充它,并覆盖原始结构
  3. 我意识到我关心空结构可能很奇怪,但不幸的是,如果字段名不存在,那么我未管理的部分代码将崩溃。我查看了help structhelp subsasgn并搜索了给定的错误消息,但到目前为止我还没有找到任何提示。因此非常感谢帮助!

4 个答案:

答案 0 :(得分:4)

您可以使用deal来解决此问题:

S = struct('a',0,'b',0);
S(1) = [];

[S(:).c] = deal(0);

这导致

S = 

1x0 struct array with fields:
    a
    b
    c 

这也适用于非空结构:

S = struct('a',0,'b',0);

[S(:).c] = deal(0);

导致

S = 

    a: 0
    b: 0
    c: 0

答案 1 :(得分:2)

怎么样

S = struct('a', {}, 'b', {}, 'c', {} );

创建一个空结构?

另一种方法是将mex文件与mxAddField一起用作解决错误的方法:

  

当结构为空时,点名结构分配是非法的    在结构上使用下标。

答案 2 :(得分:2)

您可以使用setfield来解决问题。

S = struct('a', {}, 'b', {});
S = setfield(S, {}, 'c', [])

这导致

S = 

0x0 struct array with fields:
    a
    b
    c

答案 3 :(得分:1)

只需展开@Shai's answer,这里有一个简单的MEX功能:

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);
}

示例:

>> S = struct('a',{});
>> S = addfield(S, 'b')
S = 
0x0 struct array with fields:
    a
    b