Accessing data in nested structure arrays
20 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Hi everyone,
I'm trying to access data which is nested in a structure array with multiple subfields.
I tried getfield, extractfield and multiple ways to directly access what I need
Example with what I can access easily:
a.b(1).c.d = [1 2 3];
a.b(2).c.d = [3 4 5];
a.b(3).c.d = [5 6 7];
% Direct access
>> [a.b(1).c.d]
ans =
1 2 3
% Field extraction
>> extractfield(a.b(1).c,'d')
ans =
1 2 3
% Field extraction >> only at level below array
>> extractfield(a.b,'c')
ans =
1×3 cell array
{1×1 struct} {1×1 struct} {1×1 struct}
What I' missing now is something like this which results in a vector of the first elements of d for all array entries of b (>> [1 3 5])
[a.b(:).c.d(1)]
>> [1 3 5]
Looking forward to your answers and thanks in advance!
Tim
1 Commento
Risposta accettata
Stephen23
il 26 Feb 2021
Modificato: Stephen23
il 26 Feb 2021
a.b(1).c.d = [1,2,3];
a.b(2).c.d = [3,4,5];
a.b(3).c.d = [5,6,7];
Either
V = arrayfun(@(s)s.c.d(1),a.b)
Or
tmp = [a.b.c]; % comma-separated list -> concatenate scalar structures
tmp = vertcat(tmp.d); % comma-separated list -> concatenate numeric vectors
V = tmp(:,1)
4 Commenti
Stephen23
il 18 Lug 2022
Modificato: Stephen23
il 18 Lug 2022
@Tim Baur: There is no limit to how many nested levels you can access using structure dot indexing, as long as all of those indices (except the last one) return exactly one array:
S1 = struct('A',{11,12,struct('B',{21,22,struct('C',{31,32,struct('D',{41,42,43})})})})
S1(3).A(3).B(3).C(3).D % all dot indices return one array
[S1(3).A(3).B(3).C.D] % last dot index returns three arrays
As soon as any one of the other indices (not the last dot index) returns multiple items then you are generating comma-separated lists (see answer above) and you must use intermediate variables to collect/concatenate those comma-separated lists into temporary structures:
S2 = struct('A',{...
struct('B',{struct('C',{11,12,13}),struct('C',{21,22,23})}),...
struct('B',{struct('C',{31,32,33}),struct('C',{41,42,43})})});
tmp = [S2.A] % [two (1x2 structure) arrays]
tmp = [tmp(1:2).B] % [two (1x3 structure) arrays]
[tmp.C] % [six (1x1 numeric) arrays]
There is no specific rule for what level you need to do this at, because it depends entirely on how many (nested structure) arrays are returned by each dot index (which is not fixed, because the linear/subscript indexing can change as well as the size of the structure). Note that you can use GETFIELD to access one value of an arbitrarily nested structure:
getfield(S1,{3},'A',{3},'B',{3},'C',{3},'D')
While this can only get one field value, you can easily call it multiple times in a loop. Or you could write your own loop which simply keep concatenating the intermediate structures (i.e. no special treatment of comma-separated lists which only return one array) and uses your desired indexing at each level:
C = {'A','B','C';... cell array of fields and linear indices
1:2,1:2,4:5};
tmp = [S2(C{2,1}).(C{1,1})];
for k = 2:size(C,2)
tmp = [tmp(C{2,k}).(C{1,k})];
end
display(tmp)
Note that the indexing refers to the concatenated arrays, not the ones in the nested structure tree.
Più risposte (0)
Vedere anche
Categorie
Scopri di più su Matrix Indexing in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!