Home How to return the leaves of a struct as vector in Matlab?
Reply: 2

How to return the leaves of a struct as vector in Matlab?

Jonas Stein
1#
Jonas Stein Published in 2017-10-30 17:58:21Z

Often I need to access the leaves of data in a structured array for calculations. How is this best done in Matlab 2017b?

% Minimal working example:
egg(1).weight = 30;
egg(2).weight = 33;
egg(3).weight = 34;

someeggs = mean([egg.weight]) % works fine

apple(1).properties.weight = 300;
apple(2).properties.weight = 330;
apple(3).properties.weight = 340;

someapples = mean([apple.properties.weight]) %fails
weights = [apple.properties.weight] %fails too

% Expected one output from a curly brace or dot indexing expression, 
% but there were 3 results.
gnovice
2#
gnovice Reply to 2017-10-30 18:25:33Z

If only the top level is a non-scalar structure array, and every entry below is a scalar structure, you can collect the leaves with a call to arrayfun, then do your calculation on the returned vector:

>> weights = arrayfun(@(s) s.properties.weight, apple)  % To get the vector

weights =

   300   330   340

>> someapples = mean(arrayfun(@(s) s.properties.weight, apple))

someapples =

  323.3333

The reason [apple.properties.weight] fails is because dot indexing returns a comma-separated list of structures for apple.properties. You would need to collect this list into a new structure array, then apply dot indexing to that for the next field weight.

giusti
3#
giusti Reply to 2017-10-30 18:38:26Z

You can collect properties into a temporary structure array, and then use it as normal:

apple_properties = [apple.properties];
someapples = mean([apple_properties.weight]) %works

This wouldn't work if you had even more nested levels. Perhaps something like this:

apple(1).properties.imperial.weight = 10;
apple(2).properties.imperial.weight = 15;
apple(3).properties.imperial.weight = 18;
apple(1).properties.metric.weight = 4;
apple(2).properties.metric.weight = 7;
apple(3).properties.metric.weight = 8;

Not that I would advise such a structure, but it works as a toy example. In that case you could, do the same as the previous in two steps... or you could use arrayfun.

weights = arrayfun(@(x) x.properties.metric.weight, apple);
mean(weights)
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.310549 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO