Matlab - рекурсивная функция для просмотра и изменения структуры - PullRequest
1 голос
/ 28 мая 2019

У меня есть некоторые проблемы с рекурсивной функцией Matlab, которую я создал для просмотра структуры данных и изменения каждого поля, содержащего путь, начинающийся с ключевого слова.

Моя функция, которая заменяет относительный путь, начинающийся с ключевого слова, на абсолютный путь, работает отлично и уже была протестирована (например, «$ KEYWORD \ Desktop \ Documents» будет заменено на «C: \ Users \ Name \» Desktop \ Documents')

Я пытаюсь применить эту функцию к структуре данных, которая содержит много (слишком много) полей, с рекурсивной функцией. Я хочу, чтобы эта рекурсивная функция просматривала мою структуру данных, и как только она обнаруживает параметр char, начинающийся с $ KEYWORD , она меняет значение на абсолютный путь, сохраненный в параметре среды. Вот мой код:

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) на:

newStruct = browse_struct(val)

И это тоже не работает, оно полностью разрушает исходную структуру.

Я не знаю, как решить эту проблему. Может кто-то помочь мне, пожалуйста? Большое спасибо.

1 Ответ

2 голосов
/ 28 мая 2019

Проблема 1: В вашей функции вы применяете изменения к newStruct, но продолжаете использовать initStruct для новых изменений, поэтому вы отменяете предыдущие изменения на newStruct.

Решение: когда вы передаете структуру (или любой объект) функции в MATLAB, вы передаете ее по значению, поэтому исходная структура не изменяется. Вы можете просто удалить newStruct из функции и работать только с initStruct.

Проблема 2: browse_struct(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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...