Create array of “deep” struct (scalar) fields

2 次查看(过去 30 天)
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