我想使用动态字段名而不是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
答案 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