Matlab 使用动态字段名的嵌套结构访问
我希望使用动态字段名而不是设置字段来实现以下功能: 假设一个结构“myStruct”有一组嵌套结构,即Matlab 使用动态字段名的嵌套结构访问,matlab,Matlab,我希望使用动态字段名而不是设置字段来实现以下功能: 假设一个结构“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实现的。是否有一种语法可以使用动态字段名执行此操作?以下
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
下面是一个适用于标量结构的简单解决方案。把它应用到你的例子中
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
不带
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
所以你假设myStruct.a.b.c已经存在,还是需要创建它?真正的问题是你不知道嵌套结构(结构的结构)的深度,不能重新设计你的数据结构吗?结构已经存在,我知道结构的深度,但我希望能够以灵活的方式做到这一点,无论我设置的特定字段的深度如何,与设置字段行中的操作相同。我开始使用此路径是因为mlint抱怨我应该使用动态字段名而不是setfield。此外,您对上面
setfield
的调用应该返回myStruct
,否则不会更改任何内容。请注意,传入单元格数组时,不会收到mlint警告。同意。只是写了一些粗略的代码来说明我的观点。对不起,如果有任何混乱。谢谢,这是优雅的,我会怎么做。我想我希望有一个内置的函数,它不会抛出m-lint警告。谢谢,我试着在没有eval的情况下这样做。很抱歉,我在最初的问题中没有提到这一点。我认为避免像这样的评估是不值得的。速度显然不是你的首要任务。否则你就不会嵌套你的结构了!基于递归函数调用的解决方案也会很慢。我的推测甚至比EVAL还要慢。