Elegant way to extract part of a structure as an array

Hi,
I would like to be able to extract part of a structure as an array. For example, suppose I create a simple structure:
s(1).x=1;
s(1).y=2;
s(2).x=3;
s(2).y=4;
s(3).x=5;
s(3).y=6;
Now suppose I want to extract the x values for the first two parts of this structure (that is, (1).x and (2).x). So I try:
>> s([1 2]).x
ans =
1
ans =
3
I get the x values for (1) and (2), but as two separate outputs. So if I make an assignment like the following:
>> vals=s([1 2]).x
vals =
1
It only captures the first of the two outputs. I can get around this by putting the result of s([1 2]).x in a cell array, using curly braces:
>> vals={s([1 2]).x}
vals =
[1] [3]
But I actually don't want these values in a cell array; I would like them an array, with each value in a row. I can do this by the following:
>> vals=cell2mat({s([1 2]).x}')
vals =
1
3
Now I have what I want. But, my question is, is there an easier, more elegant way to do this? My conversion of the output from array to cell array and then back to array seems very convoluted.
Thanks in advance.
Andrew DeYoung
Carnegie Mellon University

7 Kommentare

Easiest way is:
vertcat(s([1 2]).x)
And it is not clearly explained in the comma separated list documentation
Tabish Badar
Tabish Badar am 12 Dez. 2018
Bearbeitet: Tabish Badar am 12 Dez. 2018
What about extracting double variables in a vector from nested structures like structA.structB.structC.var?
Another way:
extractfield(s,'y')
ans =
2 4 6
extractfield works great!
If x happened to be a string variable, like a filename, the following works well: char({s(:).x})
An easier way to do this would be simply typing:
vals = [s([1 2]).x]
or
vals = [s([1 2]).x]'
to get a row/column vector for the answers to s(1).x and s(2).x

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

Matt Fig
Matt Fig am 10 Mai 2011

25 Stimmen

vals = [s(1:2).x]

6 Kommentare

It does not work for me. It concatenates my arrays, so that if the field "analysis" of the variable "data" is made up of 10 arrays 1x100000, I get one array 1x1000000.
For i going from 1 to 10 I get
size(data(i).analysis)
ans =
1 100000
By doing
c=[data(:).analysis];
I get
size(c)
ans =
1 1000000
So this instruction does not work for me.
Am I wrong?
I found the solution.
Using vertcat solved the problems.
Thanks
Af
Af am 15 Sep. 2020
what if the elements are strings and cannot be concatanated in anyways? it does not even get it as a cell array.
then you have to create a cell array using curly braces
vals = {s(1:2).x}
This is great, but what would be an equivalent of this if I have a more nested struct?
e.g.
s(1).x.a = 1
s(1).x.b = 10
s(1).y = 'one'
s(2).x.a = 2
s(2).x.b = 20
s(2).y = 'two'
When trying to get the array
[s.x.a]
it throws an error saying "Intermediate dot '.' indexing produced a comma-separated list with 2 values, but it must produce a single value when followed by subsequent indexing operations."
Is there an elegant way to do an equivalent to [s.x.a] that does not throw an error? The output I would like to see in this example would be [1 2].
It's not quite as pretty, but it does seem you can do it if you use two lines rather than one.
x = [s.x]
This bit creates a struct with just the information associated with x.
Then
[x.a]
should give you the output [1 2] that you're looking for.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Kategorien

Gefragt:

am 10 Mai 2011

Kommentiert:

am 6 Dez. 2023

Community Treasure Hunt

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

Start Hunting!

Translated by