Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.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_Recursion_Struct - Fatal编程技术网

Matlab-递归函数,用于浏览和修改结构

Matlab-递归函数,用于浏览和修改结构,matlab,recursion,struct,Matlab,Recursion,Struct,为了浏览数据结构并修改包含以关键字开头的路径的每个字段,我创建了一个Matlab递归函数,但该函数遇到了一些问题 用绝对路径替换以关键字开头的相对路径的My函数工作得非常好,并且已经过测试(例如,“$keyword\Desktop\Documents”将替换为“C:\Users\Name\Desktop\Documents”) 我试图用递归函数将此函数应用于包含许多(太多)字段的数据结构。我希望这个递归函数能够浏览我的数据结构,一旦它检测到以$KEYWORD开头的char参数,它就会通过存储在环

为了浏览数据结构并修改包含以关键字开头的路径的每个字段,我创建了一个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