Performing Action to ALL 'struct' Variables

Is there a way to perform the same action on several variables of type 'struct'?
In my case, I have 30 separate 'struct' variables (with non-logical names), and each of them contains a single vector of 200 elements. I only want to deal with the second half of these elements so I need something like:
struct_name = struct_name.data(100:end)
But need to keep the name of the struct variable intact. Does anyone have any suggestions?
I hope this made sense!

 Respuesta aceptada

Matt Fig
Matt Fig el 19 de Mayo de 2011
% Create several structures with different names...
structn.dat = 1:10;
structm.dat = 1:10;
structk.dat = 1:10;
% Now edit the data.
save mystructs structn structm structk
X = load('mystructs');
F = fieldnames(X);
for ii = 1:length(F)
X.(F{ii}).dat = X.(F{ii}).dat(5:10);
end
% Check
X.structm.dat

8 comentarios

Fangjun Jiang
Fangjun Jiang el 19 de Mayo de 2011
Matt, the end results are not exactly what Philip wants because the new data are in the fields of X. I think he wants structn, structm and structk etc. still exist in the workspace but has half the data. I am trying to think of a way without using eval.
Matt Fig
Matt Fig el 19 de Mayo de 2011
You are correct that this isn't exactly what was asked for, but I was waiting to see whether Philip could live with it, and whether or not the final field of each structure is actually the same or not...
To get exactly what Philip wants, replace the line inside the FOR loop with:
eval([F{ii},'.dat = X.',F{ii},'.dat(5:10)'])
Of course this may be one use for EVAL that is o.k. because the data was given to him in a messy way in the first place... If it were me, I would keep one structure, X, in place of many structures as it is easier to deal with just one structure using dynamic fieldnames than many using EVAL.
Philip
Philip el 19 de Mayo de 2011
Thanks for all your help! Actually, I am loading these files in from .mat files over many folders and subfolders, so it is possible that I could take your advice and have a single structure X with the data from each of these .mat files inside.
However, it is important that I constantly know which entry refers to which .mat file. Can I therefore have a structure and address it as 'struct.cy' and 'struct.de' etc??
Walter Roberson
Walter Roberson el 19 de Mayo de 2011
yes except for literally naming it "struct" as that conflicts with struct() as a function name.
Philip
Philip el 19 de Mayo de 2011
Ah, yes of course! Thank you for pointing that out!
Perhaps there is an altogether easier way of doing what I am trying to do - allow me to give a more thorough description.
At the moment, the .mat files are spread over many subfolders, and I don't want to have to move them all around. My current method gathers the path of all of the .mat files I am interested in, and stores the path in a cell array called 'files'. Similarly, just the names of the .mat files (without the .mat extension) are stored in a cell array called 'filenames'.
I then loop through numel(files) and check the 'files' cell array one by one, and use eval to create a variable with the same name as the filename:
for i=1:numel(filenames)
var_name = filenames{i};
eval([var_name '= load(files{i});']);
end
Is there a way I can alter the eval line so that var_name is an attribute of the structure? Perhaps the 'dat(1:5)=[];' given by Fangjun Jiang could also be incorporated?
Thanks again!
Walter Roberson
Walter Roberson el 19 de Mayo de 2011
var_name = genvarname(filenames{i});
MyStruct.(var_name) = load(files{i});
Philip
Philip el 19 de Mayo de 2011
Perfect - thanks for your help!! Now to work out how to get just the last 100 elements for each!
Thanks again!
Walter Roberson
Walter Roberson el 19 de Mayo de 2011
Editada: per isakson el 25 de Feb. de 2018
SFN = fieldnames(MyStruct);
for K = 1 : length(SFN)
var_name = SFN{K};
VFN = fieldnames(MyStruct.(var_name));
for N = 1 : length(VFN)
this_field = VFN{N};
if isvector(MyStruct.(var_name).(this_field)) & ...
length(MyStruct.(var_name).(this_field)) > 100
MyStruct.(var_name).(this_field) = MyStruct.(var_name).(this_field)(1:100);
end
end
end

Iniciar sesión para comentar.

Más respuestas (1)

Fangjun Jiang
Fangjun Jiang el 19 de Mayo de 2011
Would this help?
a(200).b=1;
a(200).c=0;
NewStruct=a(100:end);
Or, Do you mean keep the struct variable name, not the field names:
a(1:99)=[];
Now I think you mean this:
a.Data=1:200;
a.Data(1:100)=[]

1 comentario

Philip
Philip el 19 de Mayo de 2011
Apologies - I feared I wasn't very clear.
I meant to say that I have 30 separate variables (of type 'struct'), and each of these has a different name (i.e. fh, cy, de, it etc..). Now, instead of each of them containing 200 elements, I want to 'update' each of them so that they each contain only the last 100.

Iniciar sesión para comentar.

Categorías

Más información sobre Variables en Centro de ayuda y File Exchange.

Preguntada:

el 19 de Mayo de 2011

Editada:

el 25 de Feb. de 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by