Accessing Nth element of a given field for all elements in a non-scalar structure.

조회 수: 12 (최근 30일)
dandan
dandan 2018년 2월 5일
편집: Stephen23 2018년 2월 6일
I have a 1xM non-scalar structure with a field with N elements. For example (with M=3 and N=10):
for N=1:10;
s(1).x{N} = rand(100,1);
s(2).x{N} = 5.*rand(100,1);
s(3).x{N} = rand(100,1)./3;
end
and I want to create a new cell array out of the nth element of all M structure elements (sorry for the confusing phrasing, I'm not sure if there's a better way to refer to this?), for example:
a = {s(1).x{n} s(2).x{n} s(3).x{n}};
But I'd like to do this without referencing all M structure elements (1:3 in this example), because in reality there are a lot more than M=3.
So far I've tried:
a = s.x{n};
a = {s.x{n}};
a = deal(s(:).x{n});
and a few other variants, but everything just gives me an error of "Expected one output from a curly brace or dot indexing expression, but there were 2 results."
Is there a simple syntax for doing this, or do I really need to write out all M elements or use a for loop or something? Thanks!

답변 (2개)

Stephen23
Stephen23 2018년 2월 5일
편집: Stephen23 2018년 2월 5일
for N=1:10;
s(1).x{N} = rand(100,1);
s(2).x{N} = 5.*rand(100,1);
s(3).x{N} = rand(100,1)./3; % fixed the incorrect parentheses.
end
You could try getfield:
n = 4;
getfield(s,{':'},'x',{n})
or if that does not work then you could use arrayfun:
n = 4;
arrayfun(@(S)S.x(n),s)
Note the choice of parentheses is significant!
  댓글 수: 2
dandan
dandan 2018년 2월 5일
편집: dandan 2018년 2월 5일
Thank you for the suggestions! The second option works, although I actually need the curly brackets around {n} to output each cell as a double array rather than getting a cell array of cells (also the 'uniform', false option):
c=arrayfun(@(S)S.x{n},s,'uniform',0)
c =
1×2 cell array
[100×1 double] [100×1 double] [100×1 double]
versus
c=arrayfun(@(S)S.x(n),s,'uniform',0)
c =
1×2 cell array
{1×1 cell} {1×1 cell} {1×1 cell}
But your first suggestion seems to ignore the {':'} and just pulls the first structure index for some reason,
a=getfield(s,{':'},'x',{n})
a =
cell
[100×1 double]
where the result is equivalent to
a = s(1).x{n};
If there's any additional syntax that would make this approach work as well, I'd appreciate your thoughts... I'm still learning how to correctly use structures, so anything that can help me understand referencing is really helpful. Thanks!
Stephen23
Stephen23 2018년 2월 6일
편집: Stephen23 2018년 2월 6일
@dandan: my answer does not use the uniformoutput option, all you need is this:
c = arrayfun(@(S)S.x(n),s)
This works because the field x is a cell array, therefore getting element n using () parentheses returns a scalar cell array: a scalar cell array is a uniform output, and so there is no need to set uniformoutput to false.

댓글을 달려면 로그인하십시오.


Walter Roberson
Walter Roberson 2018년 2월 5일
arrayfun(@(S) S.x{n}, s)
  댓글 수: 2
Stephen23
Stephen23 2018년 2월 5일
??? Error using ==> arrayfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.
dandan
dandan 2018년 2월 5일
This works with a minor fix to address the error above:
arrayfun(@(S) S.x{n}, s, 'uniform', false)
Thanks!

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Structures에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by