필터 지우기
필터 지우기

Create array of “deep” struct (scalar) fields

조회 수: 2 (최근 30일)
Jorge
Jorge 2019년 8월 11일
답변: Jorge 2019년 8월 12일
Hi! How can I collapse the values of "deep" struct fields into arrays by just indexing?
In the example below, I can only do it for the "top-most" level, and for "deeper" levels I get the error:
"Expected one output from a curly brace or dot indexing expression, but there were XXX results."
The only workaround I found so far is to unfold the operation into several steps, but the deeper the structure the uglier this gets.
clc; clear variables;
% Dummy data
my_struc.points(1).fieldA = 100;
my_struc.points(2).fieldA = 200;
my_struc.points(3).fieldA = 300;
my_struc.points(1).fieldB.subfieldM = 10;
my_struc.points(2).fieldB.subfieldM = 20;
my_struc.points(3).fieldB.subfieldM = 30;
my_struc.points(1).fieldC.subfieldN.subsubfieldZ = 1;
my_struc.points(2).fieldC.subfieldN.subsubfieldZ = 2;
my_struc.points(3).fieldC.subfieldN.subsubfieldZ = 3;
my_struc.info = 'Note my_struc has other fields besides "points"';
% Get all fieldA values by just indexing (this works):
all_fieldA_values = [my_struc.points(:).fieldA]
% Get all subfieldM values by just indexing (doesn't work):
% all_subfieldM_values = [my_struc.points(:).fieldB.subfieldM]
% Ugly workaround:
temp_array_of_structs = [my_struc.points(:).fieldB];
all_subfieldM_values = [temp_array_of_structs.subfieldM]
% Get all subsubfieldZ values by just indexing (doesn't work):
% all_subsubfieldZ_values = [my_struc.points(:).fieldC.subfieldN.subsubfieldZ]
% Ugly workaround:
temp_array_of_structs1 = [my_struc.points(:).fieldC];
temp_array_of_structs2 = [temp_array_of_structs1.subfieldN];
all_subsubfieldZ_values = [temp_array_of_structs2.subsubfieldZ]
Output:
all_fieldA_values =
100 200 300
all_subfieldM_values =
10 20 30
all_subsubfieldZ_values =
1 2 3
Thanks for any help!

채택된 답변

Jorge
Jorge 2019년 8월 12일
Thanks for the answers & comments; turns out it's possible to use arrayfun() to this purpose!:
all_subfieldM_values = arrayfun(@(in) in.fieldB.subfieldM, my_struc.points)
all_subsubfieldZ_values = arrayfun(@(in) in.fieldC.subfieldN.subsubfieldZ, my_struc.points)
This achieves the desired effect with a single line of code :)

추가 답변 (1개)

TADA
TADA 2019년 8월 11일
As always, you can use a small utility function to drill down the object hierarchy
It's probably not the most elegant solution because you have to write the field names as strings, so don't expect any intellisence there, but hey, subsref does the same thing so...
function b = drillref(a, s)
fields = strsplit(s, '.');
b = a;
for i = 1:numel(fields)
b = [b.(fields{i})];
end
end
A = drillref(my_struc, 'points.fieldA')
A =
100 200 300
B_M = drillref(my_struc, 'points.fieldB.subfieldM')
B_M =
10 20 30
C_N_Z = drillref(my_struc, 'points.fieldC.subfieldN.subsubfieldZ')
C_N_Z =
1 2 3

카테고리

Help CenterFile Exchange에서 Structures에 대해 자세히 알아보기

제품


릴리스

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by