Using Set Field for multiple depths
7 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hi,
I'd like to set a particular element of a structure array with a dynamic index to a field. So, for example, if fieldNames={'a' 'b' 'c'} and fieldValue=3, I want to set myStruct.a.b.c=3. I can hack together something that uses the eval function, say for example
str=['myStruct'];
for ii=1:length(fieldnames)
str=[str '.('''];
str=[str fieldnames{ii}];
str=[str ''')'];
end
eval([str '=' num2str(fieldValue)])
But is there a way to do this without using eval? I tried looking at setfield, but I can't get it to work. Running
x.a.b.c=3;
fieldnames={'a' 'b' 'c'};
getfield(x,fieldnames{:})
successfully returns 3, but running
setfield(x,fieldnames{:},5)
doesn't seem to do anything
Thanks
Brendan
0 commentaires
Réponse acceptée
Walter Roberson
le 9 Mai 2012
You will not be able to do this using setfield() or getfield(), not in any useful way.
You should refer to subsref() and subsassgn(). They are a bit clumsy to use, but they can handle the task.
Plus de réponses (1)
Daniel Shub
le 9 Mai 2012
If it is always 3 deep then you can just do
myStruct.(fieldnames{1}).(fieldnames{2}).(fieldnames{3}) = fieldValue;
A little bit more general is
switch length(fieldnames)
case 1
myStruct.(fieldnames{1}) = fieldValue;
case 2
myStruct.(fieldnames{1}).(fieldnames{2}) = fieldValue;
case 3
myStruct.(fieldnames{1}).(fieldnames{2}).(fieldnames{3}) = fieldValue;
end
You can obviously extend this to any N you want.
A truly robust solution would be to do this recursively.
function S = rsetfield(S, field, V)
if length(field) > 1
S.(field{1}) = rsetfield(S.(field{1}), field(2:end), V);
else
S.(field{1}) = V;
end
end
You would want to do some input checking to make sure everything is happy. I have no idea how inefficient this is.
0 commentaires
Voir également
Catégories
En savoir plus sur Structures dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!