Как избежать eval при назначении данных в массив массивов - PullRequest
2 голосов
/ 03 апреля 2012

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

Затем у меня есть строка с именем IndexString, которая является индексом дляопределенное подполе StructArray, и оно может содержать несколько индексов для различных структурных массивов и массивов ячеек, например: 'SubjectData(5).fmriSessions{2}.Stats' или 'SubjectData(14).TestResults.Test1.Factor{4}.Subfactor{3}'.

И тогда у меня есть переменная с именем DataToBeEntered, котораяможет иметь любой тип данных MATLAB, обычно это какой-либо структурный массив, массив ячеек или матрица.

Используя eval, легко ввести данные в поле или ячейку, индексированные с помощью IndexString:

eval([ 'AnalysisResults.', IndexString, ' = DataToBeEntered;' ])

Но можно ли избежать использования eval в этом?setfield не работает для этого.

Спасибо:)

Ответы [ 2 ]

5 голосов
/ 03 апреля 2012

Ну, eval, конечно, самый простой, но и самый грязный способ.

"Правильный" способ сделать это, я думаю, будет использовать subsasgn,Вам нужно будет разобрать частичную команду MATLAB (например, SubjectData(5).fmriSessions{2}.Stats) в правильное представление для этих функций.Часть работы может быть выполнена с помощью substruct, но это самая легкая часть.

Так, например, SubjectData(5).fmriSessions{2}.Stats необходимо будет перевести на

indexes = {'.' , 'SubjectData',
           '()', {5},
           '.' , 'fmriSessions',
           '{}', {2},
           '.' , 'Stats'};
indexStruct = substruct(indexes{:});
AnalysisResult = subsasgn(AnalysisResult, indexStruct, DataToBeEntered);

Где вы должны разработать код так, чтобы массив ячеек indexes был выполнен, как указано выше.Это не должно быть так сложно, но это тоже не тривиально.В прошлом году я портировал некоторый eval -тяжелый код с аналогичной целью, и это казалось легким, но довольно сложно все сделать правильно.

1 голос
/ 03 апреля 2012

Вы можете использовать динамические имена полей:

someStruct.(someField) = DataToBeEntered;

где someField - это переменная, содержащая имя поля, но вам придется проанализировать IndexString для одного имени поля и индексов.

...