Access to array of structs (no for loops)
36 次查看(过去 30 天)
显示 更早的评论
Dear All,
From an array of structs I want to access all last elements of field datarow using one command.
Construct the array of structs:
%init struct
rec.datarow = [1,2,3,4,5];
rec.datacol = [1,2,3,4,5]';
rec.name = 'apple';
%init array of structs
rec(2:3) = rec;
Access fields name, datarow, datacol and last element of datarow of first struct. No problem here.
%get field name of all structs in once using comma-separated lists
allnames = {rec.name}
%get field datarow of all structs in once using comma-separated lists
alldatarow = [rec.datarow]
%get field datacol of all structs in once using comma-separated lists
alldatacol = [rec.datacol]
%get end value of field datarow of first struct
v1 = rec(1).datarow(end)
It appear to be sensible to store data in column format because the collection in comma separated lists yields in a handy matrix.
Now my question: Is there a way to access all end values of datarow with one command (no for loops or temporary variables)?
I was expecting that the following command should work:
%but how to get the end values of datarow of all structs in once??
allendvalues = [rec.datarow(end)]
But I get this error: Expected one output from a curly brace or dot indexing expression, but there were 3 results
Anyone some ideas?
Patrick
0 个评论
采纳的回答
Stephen23
2019-5-5
编辑:Stephen23
2019-5-5
"Is there a way to access all end values of datarow with one command (no for loops or temporary variables)?"
Nope.
"Anyone some ideas?"
You could hide the loop inside a cellfun or an arrayfun call (but an explicit loop is usually more efficient):
>> arrayfun(@(s)s.datarow(end),rec)
ans =
5 5 5
The cause of that error message is explained here:
You can learn about comma-separated lists here:
0 个评论
更多回答(3 个)
dpb
2019-5-5
Is expressly noted that ML does NOT support array indexing for more than a single struct array element expression--see Note @ https://www.mathworks.com/help/matlab/matlab_prog/access-data-in-a-structure-array.html Unfortunate, but true...
It seems by documentation one should be able to use getfield to write a generic expression to do so, but I've never been able return what I thought should be returned by what (pretty opaque) documentation seems to infer should work..
>> getfield(rec,{1,3},'datarow',{3})
ans =
3
>>
would appear that should return two values but somehow is only one. I've no explanation for what's going on here.
Such kinds of issues are why I've basically given up even trying more complicated things with struct, the grief just ain't been worth the potential benefit without a real application to make use thereof... :)
For your problem; best I've been able to do would be two-step process; you can return the whole field from the struct array as a 2D array and then do the column selection from that array. That could be wrapped in a user-function for syntax ease, but I've figured no way to write the indexing expression you would like.
You could, I think, (but I've not pursued) use the arrayfun() route with anonymous function that would operate on the element and just catenate the results, but that's a lot of overhead and obfuscation.
0 个评论
Image Analyst
2019-5-5
Try this:
allValues = [rec.datarow]; % String together into single vector.
allendvalues = allValues(5:5:end) % Subsample. Assumes all datarows have 5 elements
1 个评论
dpb
2019-5-5
My suggested soltuion, IA, as the two-step process... :)
Octave has such second-level addressing syntax features for at least some constructs; whether it's general for struct arrays I don't know. While I recognize it's undoubtedly tough nut for the parser in general, surely seems need for TMW to go this route -- I think it would be much more valuable than many of the things they have introduced recently, meself....
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Structures 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!