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

13 visualizaciones (últimos 30 días)
Michael
Michael el 7 de Ag. de 2023
Comentada: Michael el 7 de Ag. de 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 comentarios
Stephen23
Stephen23 el 7 de Ag. de 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 el 7 de Ag. de 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.

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
Michael
Michael el 7 de Ag. de 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];
}

Iniciar sesión para comentar.

Categorías

Más información sobre Structures en Help Center y File Exchange.

Productos


Versión

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by