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

4 views (last 30 days)
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 Comments
Stephen23
Stephen23 on 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 on 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.

Sign in to comment.

Answers (1)

Benjamin
Benjamin on 7 Aug 2023
Edited: Benjamin on 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 Comment
Michael
Michael on 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];
}

Sign in to comment.

Categories

Find more on Structures in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!