Implicit indexing with structures - A question
Ältere Kommentare anzeigen
It is by NO WAY clear to me why this code makes sense
clear all ;
a.x = 1
b.x = 2
s = [a,b]
ANS = [s(:).x]
and why this one does not
clear all ;
a.p.x = 1
b.p.x = 11
s = [a,b]
ANS = [s(:).p.x]
The question rises from the fact that I have data stored in the second format. I can succesfully access to
s(15).p.x % x is a scalar
s(15).q.x % assuming there is also a q field
But I can't do
s(:).p.x
What is the fastest way of overcoming that?
tnx!
Mike
Antworten (2)
John D'Errico
am 22 Aug. 2017
Bearbeitet: John D'Errico
am 22 Aug. 2017
It is not at all clear what does not make sense.
clear all ;
a.x = 1;
b.x = 2;
So, a and b are structs, each with field x.
s = [a,b];
s is a 1x2 struct. Each element of s is a struct.
ANS = [s(:).x]
ANS =
1 2
Extract the field x from each of the elements of s. The result will be a comma separated list. Combine them into one array, using [], thus horzcat.
In the second case, you have done something different.
a.p.x = 1;
b.p.x = 11;
s = [a,b];
ANS = [s(:).p.x]
Expected one output from a curly brace or dot indexing expression, but there were 2 results.
First of all, you put 11 into the second spot. ;-) Ok, that is not significant.
s s = 1×2 struct array with fields: p
So s is now a struct array, with field p.
ANS = [s(:).p]
ANS =
1×2 struct array with fields:
x
So I can extract the p field of those struct elements. Again, it is a comma separated list.
s(:).p
ans =
struct with fields:
x: 1
ans =
struct with fields:
x: 11
You cannot index a comma separated list. Remember that MATLAB works from left to right.
s(:)
ans =
2×1 struct array with fields:
p
s(:) is a struct array. I can extract the p field of that. But since the result is a comma separated list, not another struct, I cannot form s(:).p.x as you wish.
Nor can it be done as:
[s(:).p].x
[s(:).p].x
↑
Error: Unexpected MATLAB operator.
The solution is simple enough. Break it into two consecutive operations.
temp = [s(:).p];
[temp.x]
ans =
1 11
5 Kommentare
Moritz Morawietz
am 10 Jan. 2018
Hi :)
This works well for reading, but what about setting the values? If i want to set a.p.x= [2,3] for example, the solution with the temporary variable won't work.
Vijay Venkatasubramanian
am 20 Jun. 2019
I am maybe a year-and-a-half late to this question, but I have a `50 x 1` struct array and I would like to do something like this.
I have `Position` as a field in my structures and I have to assign a random value to each of them. So I do,
struct(1:50).Position = rand(1,2);
It gives me an error, saying
Expected one output from a curly brace or dot indexing expression, but there were 50 results.
Is there a way to assign them without having to write a loop?
Thanks!
I seem to remember there is some syntax that works, though I may be wrong. If there is I always forget what it is or how to work it out.
However, I use the 3rd party disperse function from the File Exchange:
which will do this for you
e.g.
s(50).a = 7; % create an array of structs with a field 'a';
[ s.a ] = disperse( rand(50,1) ); % copy one element of the input to an element out the output
I'm not sure if there is a syntax that works if you want a (1,2) size array assigned to each element of the struct's 'a' field though.
@Adam: In your case you distribute the 50 random elements to 50 scalar fields of the struct array. Vijay asked to setting the field Position of all 50 elements of the struct array to the same [1x2] vector. This is a difference.
@Vijay Venkatasubramanian:
[S(1:50).Position] = deal(rand(1,2))
To distribute different values to the fields:
c = num2cell(rand(1, 50));
[s(1:50).Position] = c{:};
Adam
am 21 Jun. 2019
I assumed 'a random value to each of them' meant a different one to each, but certainly it is neater to use your 2nd approach, which is the one I couldn't remember, than relying on 3rd party functions :)
You can just do it in two lines:
stuff = [s.p];
result = [ stuff.x ];
(yes, I always have trouble naming random intermediate results that I don't care about!)
Incidentally, the (:) is un-necessary.
Kategorien
Mehr zu Structures finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!