Matlab-递归函数,用于浏览和修改结构
为了浏览数据结构并修改包含以关键字开头的路径的每个字段,我创建了一个Matlab递归函数,但该函数遇到了一些问题 用绝对路径替换以关键字开头的相对路径的My函数工作得非常好,并且已经过测试(例如,“$keyword\Desktop\Documents”将替换为“C:\Users\Name\Desktop\Documents”) 我试图用递归函数将此函数应用于包含许多(太多)字段的数据结构。我希望这个递归函数能够浏览我的数据结构,一旦它检测到以$KEYWORD开头的char参数,它就会通过存储在环境参数中的绝对路径更改该值。 这是我的密码:Matlab-递归函数,用于浏览和修改结构,matlab,recursion,struct,Matlab,Recursion,Struct,为了浏览数据结构并修改包含以关键字开头的路径的每个字段,我创建了一个Matlab递归函数,但该函数遇到了一些问题 用绝对路径替换以关键字开头的相对路径的My函数工作得非常好,并且已经过测试(例如,“$keyword\Desktop\Documents”将替换为“C:\Users\Name\Desktop\Documents”) 我试图用递归函数将此函数应用于包含许多(太多)字段的数据结构。我希望这个递归函数能够浏览我的数据结构,一旦它检测到以$KEYWORD开头的char参数,它就会通过存储在环
function newStruct = browse_struct(initStruct)
fields = fieldnames(initStruct);
n_fields = length(fields);
for n = 1 : n_fields
val = getfield(initStruct, fields{n});
if isstruct(val)
browse_struct(val);
elseif( ischar(val) && val(1)=='$' )
newVal = replace_keyword(val);
newStruct = setfield(initStruct, fields{n}, newVal);
end
end
end
当我在调试模式下运行我的代码时,我看到我的函数完全浏览我的数据结构,并且感兴趣的字段被我想要的替换,但是当运行结束时,新结构与初始结构相同。没有字段被更改,所以最后我仍然有以$KEYWORD开头的相对路径,而它应该是一个绝对路径
我还尝试将第7行(仅在if条件下)替换为:
它也不起作用,它完全破坏了最初的结构
我不知道如何解决那个问题。有人能帮我吗?非常感谢。问题1:在您的函数中,您正在将更改应用于
newStruct
,但继续使用initStruct
进行新更改,因此您正在覆盖以前对newStruct
的更改
解决方案:在MATLAB中将结构(或任何对象)传递给函数时,按值传递,因此原始结构不会改变。您只需从函数中删除newStruct
,并且只能使用initStruct
问题2:浏览结构(val)代码>不更改结构,并且newStruct=browse_struct(val)代码>将结构更改为其字段
解决方案:使用newStruct=setfield(initStruct,fields{n},browse_struct(val))代码>
修正后的功能:
function initStruct = browse_struct(initStruct)
fields = fieldnames(initStruct);
n_fields = length(fields);
for n = 1 : n_fields
val = getfield(initStruct, fields{n});
if isstruct(val)
initStruct = setfield(initStruct, fields{n}, browse_struct(val));
elseif( ischar(val) && val(1)=='$' )
newVal = replace_keyword(val);
initStruct = setfield(initStruct, fields{n}, newVal);
end
end
end
与使用getfield
和setfield
不同,MATLAB建议“将动态字段名与结构一起使用”,因此您可以修改如下函数:
function initStruct = browse_struct(initStruct)
fields = fieldnames(initStruct);
n_fields = length(fields);
for n = 1 : n_fields
val = initStruct.(fields{n});
if isstruct(val)
initStruct.(fields{n}) = browse_struct(val);
elseif( ischar(val) && val(1)=='$' )
newVal = replace_keyword(val);
initStruct.(fields{n}) = newVal;
end
end
end
您正在处理struct
的两个不同实例,分别名为val
和newstruct
。当递归函数启动时,应该分配newStruct=initStruct代码>开始,然后对该新闻结构进行修改(如果/必要),然后将其作为输出返回。嗨,Hoki,谢谢你的建议。我添加了newStruct=initStruct代码>在代码的开头,但它不会改变任何东西…非常感谢Eliahu Aaron。多亏了你出色的解释,我才更好地理解我的错误。现在它工作得非常好。很好地解释了递归函数的微妙之处(与MATLAB一起按值传递一切)+1 ;)
function initStruct = browse_struct(initStruct)
fields = fieldnames(initStruct);
n_fields = length(fields);
for n = 1 : n_fields
val = initStruct.(fields{n});
if isstruct(val)
initStruct.(fields{n}) = browse_struct(val);
elseif( ischar(val) && val(1)=='$' )
newVal = replace_keyword(val);
initStruct.(fields{n}) = newVal;
end
end
end