2015-07-06 3 views
0

У меня есть несколько файлов «2011-01-01.txt», «2013-01-02.txt», «2015-02-01.txt» и т. Д. Я хочу создать переменную-структуру для каждого файла таким образом, что (значения составляют):Динамически называть структурную переменную в MATLAB

machine20110101.size=[1,2,3]; 
machine20110101.weight=2345; 
machine20110101.price=3456; 

machine20130102.size=[2,3,4]; 
machine20130102.weight=1357; 
machine20130102.price=123; 

machine20150201.size=[1,2,4]; 
machine20150201.weight=1357; 
machine20150201.price=123; 

И,

save('f20110101.mat','machine20110101'); 
save('f20130102.mat','machine20130102') ; 
save('f20150201.mat','machine20150201'); 

Как мы видим, имена Struct являются производными от имен файлы , Как я могу построить вышеуказанные структурные переменные?

Я искал какое-то время, но я не понял, как использовать genvarname.

И эти ссылки (dynamic variable names in matlab, dynamic variable declaration function matlab, Dynamically change variable name inside a loop in MATLAB) не решили мою проблему.

Я использую MATLAB R2012b, поэтому функции, такие как matlab.lang.makeUniqueStrings, определенные после этой версии, недоступны.

+5

Литературный ответ на вопрос включает ['eval'] (http://www.mathworks.com/help/matlab/ref/eval.html), который я бы настоятельно рекомендовал против этого. Вместо этого вычеркните черты из имени файла (полученные с помощью ['fileparts'] (http://www.mathworks.com/help/matlab/ref/fileparts.html) с помощью [' strrep'] (http: // www.mathworks.com/help/matlab/ref/strrep.html) или ['regexprep'] (http://www.mathworks.com/help/matlab/ref/regexprep.html), чтобы [использовать в качестве имени поля] (http://www.mathworks.com/help/matlab/matlab_prog/generate-field-names-from-variables.html) для вложенной структуры (например, mydata.machine20110101) – excaza

+0

именно с использованием 'fileparts' и' strrep' намного лучше, чем 'genvarname', который в соответствии с Matlab скоро будет удален ... – scmg

+1

Это возможно, если вы используете трюки в приведенных выше комментариях. Тем не менее, это дизайн, который я бы рекомендовал против. Следующая проблема, с которой вы столкнетесь, заключается в том, что вы в остальной части кода не будете знать имя переменной. Вам придется адаптировать код для обработки этой магии. Это также может сделать код трудным для чтения для людей, следующих за ним. Наиболее распространенным решением этой проблемы является добавление поля 'name' или' tag'. Вы можете сохранить машину имен переменных и использовать имя типа '' 20110101'' или 'machine20110101'. Обратите внимание, что это необходимо обработать при чтении файла, чтобы избежать перезаписи. – patrik

ответ

0

Теперь, когда я нахожусь перед MATLAB, вот пример, основанный на мой комментарий выше, используя dynamic field names с именами файлов обрезают с помощью fileparts и regexprep в cellfun вызова.

% Sample list for testing here, use uigetdir with dir or whatever method to 
% get a list of files generically 
filelist = {'C:\mydata\2011-01-01.txt', ... 
       'C:\mydata\2012-02-02.txt', ... 
       'C:\mydata\2013-03-03.txt', ... 
       'C:\mydata\2014-04-04.txt', ... 
       }; 
nfiles = length(filelist); 

% Get filenames from your list of files 
[~, filenames] = cellfun(@fileparts, filelist, 'UniformOutput', false); 

% Prune unwanted characters from each filename and concatenate with 'machine' 
prunedfilenames = regexprep(filenames, '-', ''); 
myfieldnames = strcat('machine', prunedfilenames); 

% Generate your structure 
for ii = 1:nfiles 
    % Parse your files for the data, using dummy variables since I don't 
    % know how your data is structured 
    loadedsize = [1, 2, 3]; 
    loadedweight = 1234; 
    loadedprice = 1234; 

    % Add data to struct array 
    mydata.(myfieldnames{ii}).size = loadedsize; 
    mydata.(myfieldnames{ii}).weight = loadedweight; 
    mydata.(myfieldnames{ii}).price = loadedprice; 
end 

@patrik вызывает некоторые хорошие моменты в комментариях. Я думаю, что более общий метод, он хотел бы видеть (пожалуйста, поправьте меня, если я ошибаюсь) идет что-то вроде этого:

% Sample list for testing here, use uigetdir with dir or whatever method to 
% get a list of files generically 
filelist = {'C:\mydata\2011-01-01.txt', ... 
       'C:\mydata\2012-02-02.txt', ... 
       'C:\mydata\2013-03-03.txt', ... 
       'C:\mydata\2014-04-04.txt', ... 
       }; 
nfiles = length(filelist); 

% Get filenames from your list of files 
[~, filenames] = cellfun(@fileparts, filelist, 'UniformOutput', false); 

% Prune unwanted characters from each filename and concatenate with 'machine' 
prunedfilenames = regexprep(filenames, '-', ''); 
mytags = strcat('machine', prunedfilenames); 

% Preallocate your structure 
mydata = repmat(struct('tag', '', 'size', [1, 1, 1], 'weight', 1, 'price', 1), nfiles, 1); 

% Fill your structure 
for ii = 1:nfiles 
    % Parse your files for the data, using dummy variables since I don't 
    % know how your data is structured 
    loadedsize = [1, 2, 3]; 
    loadedweight = 1234; 
    loadedprice = 1234; 

    % Add data to struct array 
    mydata(ii).tag = mytags{ii}; 
    mydata(ii).size = loadedsize; 
    mydata(ii).weight = loadedweight; 
    mydata(ii).price = loadedprice; 
end 
0

Кроме @ excaza отвечают, я использовал следующий подход:

machine.size = [1,2,3]; machine.price = 335; machine.weight = 234;

machineName = ['machine',the_date];

machineSet = struct(machineName,machine);

save(OutputFile,'-struct','machineSet',machineName);

Смежные вопросы