How can I access all values of a field in an array of nested structs

9 Ansichten (letzte 30 Tage)
Michael
Michael am 7 Aug. 2023
Kommentiert: Michael am 7 Aug. 2023
The following code creates an array of nested structs (length = 4).
nested_struct = struct(...
'a', 1, ...
'b', 1 ...
);
s = struct( ...
'c', 0, ...
'nested', nested_struct ...
);
array_of_nested_struct = repmat(s, 4, 1);
How can I easily access an array of all of the values of the field a ?
For example, I'd like to compute the sum as
% sum(array_of_nested_struct.nested.a)
However, this does not work because
array_of_nested_struct.nested
ans = struct with fields:
a: 1 b: 1
ans = struct with fields:
a: 1 b: 1
ans = struct with fields:
a: 1 b: 1
ans = struct with fields:
a: 1 b: 1
does not produce a struct array.
My only solution seems overly cumbersome, and requries usage of intermediate variables:
% The following is not an array of structures
array_of_nested_struct.nested;
% So convert it into a struct array
nested = [array_of_nested_struct.nested];
% Do the same for the next level
a_value_array = [nested.a];
% Finally compute sum
sum(a_value_array)
ans = 4
is there a better syntax to achieve this result? The syntax should also support code generation without any data copies
Thanks!
  2 Kommentare
Stephen23
Stephen23 am 7 Aug. 2023
"is there a better syntax to achieve this result?"
Don't spread data over lots of different structures if it is intended to be processed together.
Michael
Michael am 7 Aug. 2023
Thanks, Stephen. In this case, the data naturally wants to be this way. I actually have two substructs that need to go two different processing components.

Melden Sie sich an, um zu kommentieren.

Antworten (1)

Benjamin
Benjamin am 7 Aug. 2023
Bearbeitet: Benjamin am 7 Aug. 2023
% Given code to create the array_of_nested_struct
nested_struct = struct(...
'a', 1, ...
'b', 1 ...
);
s = struct( ...
'c', 0, ...
'nested', nested_struct ...
);
array_of_nested_struct = repmat(s, 4, 1);
% Use arrayfun to extract 'a' field values and compute the sum directly
sum_a_values = sum(arrayfun(@(x) x.nested.a, array_of_nested_struct));
% Display the sum
disp("Sum of 'a' values: " + sum_a_values);
So this here will give you the array:
array = arrayfun(@(x) x.nested.a, array_of_nested_struct)
  1 Kommentar
Michael
Michael am 7 Aug. 2023
Thanks, @Benjamin! This is much better, though still a little uneasy on the eyes.
Unfortunately, in codegen it still makes a copy of the data before performing the sum, instead of just referencing the values in place.
An example of the generated code follows (Note it's approximate - I changed some variable names).
for (c_k = 0; c_k < 4; c_k++) {
temp[c_k] = b_varargout_2[c_k].nested.a;
}
bsum_re = temp[0];
for (xblockoffset = 0; xblockoffset < 3; xblockoffset++) {
bsum_re += temp[xblockoffset + 1];
}

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Structures finden Sie in Help Center und File Exchange

Produkte


Version

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by