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

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 comentarios

"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.
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.

Iniciar sesión para comentar.

Respuestas (1)

Benjamin
Benjamin el 7 de Ag. de 2023
Editada: Benjamin el 7 de Ag. de 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 comentario

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];
}

Iniciar sesión para comentar.

Productos

Versión

R2022b

Preguntada:

el 7 de Ag. de 2023

Comentada:

el 7 de Ag. de 2023

Community Treasure Hunt

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

Start Hunting!

Translated by