How to get an array of all field elements of a 1xN structure with many fields

12 vues (au cours des 30 derniers jours)
Leo Simon le 2 Oct 2021
Commenté : Leo Simon le 3 Oct 2021
In this thread. @Sebastian asked how to get an array of all field elements of a 1xN structure. @AdamDanz answered, but his answer only applies to a single specified field of a struct. I want be able to loop through all fields of a struct and exact all elements of each field.
For example
S(1).a = 1; S(2).a = 2 ; S(1).b = 3 ; S(2).b = 4; S(1).c = [ 1, 2]; S(2).c = [ 3, 4]
[S(:).a]
[S(:).b]
etc., but naturally one wants to be able to loop thru all fields of S, as in
Fields = fieldnames(S);
for ii= 1:numel(Fields);
field = Fields{ii};
eval(['[S(:).' field ']']);
end
There has to be a less kludgy way of doing this!!! Thanks!
1 commentaireAfficher -1 commentaires plus anciensMasquer -1 commentaires plus anciens
Stephen23 le 2 Oct 2021
Modifié(e) : Stephen23 le 2 Oct 2021
"There has to be a less kludgy way of doing this!!! "
For a start, you can trivially remove that very ugly and inefficient EVAL by using dynamic fieldnames:
i.e. replace this slow, inefficient, complex, anti-pattern code:
eval(['[S(:).' field ']']) % ugh, do NOT do this!
with this neat, simple, and very efficient code:
[S(:).(field)]
or equivalently just this:
[S.(field)]
Using a FOR loop is probably the most efficient solution to your original question.

Connectez-vous pour commenter.

Réponse acceptée

Matt J le 2 Oct 2021
Modifié(e) : Matt J le 2 Oct 2021
I would recommend the attached file
S(1).a = 1; S(2).a = 2 ; S(1).b = 3 ; S(2).b = 4;
T=scalarize_struct(S)
T = struct with fields:
a: [1 2] b: [3 4]
3 commentairesAfficher 1 commentaire plus ancienMasquer 1 commentaire plus ancien
Matt J le 2 Oct 2021
scalarize_struct works for your modified example, too
S(1).a = 1; S(2).a = 2 ; S(1).b = 3 ; S(2).b = 4; S(1).c = [ 1, 2]; S(2).c = [ 3, 4];
T=scalarize_struct(S)
T = struct with fields:
a: [1 2] b: [3 4] c: {[1 2] [3 4]}
Leo Simon le 3 Oct 2021
scalarize_struct woks perfectly, thanks very much!

Connectez-vous pour commenter.

Plus de réponses (1)

Jan le 2 Oct 2021
Fields = fieldnames(S);
for ii= 1:numel(Fields);
field = Fields{ii};
[S(:).(field)]
end
[...] is the horizontal concatenation, so the line [S(:).(field)] is equivalent to:
cat(2, S(:).(field))
Maybe you want to join the vectors vertically, then use cat(1, ...). If the arrays have different sizes, you need a cell array:
{S(:).(field)}
1 commentaireAfficher -1 commentaires plus anciensMasquer -1 commentaires plus anciens
Leo Simon le 3 Oct 2021
Thanks @Jan, I accepted @Matt's answer because was a bit easier to work with in my case.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Whos 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!

Translated by