Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 使用动态字段名的嵌套结构访问_Matlab - Fatal编程技术网

Matlab 使用动态字段名的嵌套结构访问

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”有一组嵌套结构,即

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还要慢。