使用动态字段名进行嵌套结构访问

时间:2014-01-15 18:06:29

标签: matlab

我想使用动态字段名而不是setfield来实现以下功能:

假设结构'myStruct'有一组嵌套结构,即

myStruct.a.b.c = 0
myStruct.a.d = 0
myStruct.a.e.f.g = 0

我希望能够如下灵活设置叶结构值:

fields = {'a', 'b', 'c'}
paramVal = 1
setfield(myStruct, fields{:}, paramVal)

这可以使用setfield。是否有使用动态字段名称执行此操作的语法?以下显然不起作用,因为fieldname需要是一个字符串而不是一个数组,但演示了我想要的东西:

myStruct.(fields{:}) = 0

这相当于:

myStruct.('a').('b').('c') = 0

2 个答案:

答案 0 :(得分:2)

没有eval的递归解决方案,从我的一个旧实用程序函数中删除:

function s = setsubfield(s, fields, val)

if ischar(fields)
    fields = regexp(fields, '\.', 'split'); % split into cell array of sub-fields
end

if length(fields) == 1
    s.(fields{1}) = val;
else
    try
        subfield = s.(fields{1}); % see if subfield already exists
    catch
        subfield = struct(); % if not, create it
    end
    s.(fields{1}) = setsubfield(subfield, fields(2:end), val);
end

我猜try/catch可以替换为if isfield(s, fields{1}) ...,我不记得为什么我这样编码了。

用法:

>> s = struct();
>> s = setsubfield(s, {'a','b','c'}, 55);
>> s = setsubfield(s, 'a.b.d.e', 12)
>> s.a.b.c
ans =
    55
>> s.a.b.d.e
ans =
    12

答案 1 :(得分:1)

下面是一个简单的,如果粗糙的解决方案,适用于标量结构。将它应用于您的示例,

S=setfld(myStruct,'a.b.c',1)

>> S.a.b.c

ans =

     1

但一般来说,深层嵌套的结构是不推荐的。

function S=setfld(S,fieldpath,V)
%A somewhat enhanced version of setfield() allowing one to set
%fields in substructures of structure/object S by specifying the FIELDPATH.
%
%Usage:  setfld(S,'s.f',V) will set S.s.f=V  
%                                            
%
%%Note that for structure S, setfield(S.s,'f') would crash with an error if 
%S.s did not already exist. Moreover, it would return a modified copy
%of S.s rather than a modified copy of S, behavior which would often be 
%undesirable.
%
%
%Works for any object capable of a.b.c.d ... subscripting
%
%Currently, only single structure input is supported, not structure arrays.


try
 eval(['S.' fieldpath '=V;']);
catch
 error 'Something''s wrong.';
end