How to access elements of a structure without the use of a loop ?

19 views (last 30 days)
Hi everybody,
my question sounds very simple but I cant find a way to have access to elements (values) of a structure without a loop. Here below is what I have done with the help of a loop:
for i=1:length(conf.running)
event1LFS(i)=Running{i}.SP.LFS2LMS;
end
event1LFS=mean(event1LFS);
So if you have a way like the following one (but this one does not work of course), it would be perfect. Thank you
event1LFS=mean(Running{1:end}.SP.LFS2LMS);
  2 Comments
Adam
Adam on 29 Apr 2015
It would help if you could give a small example of the cell array structure for us to test on as I don't have time personally to try to create a test array that fits the criteria, but don't mind taking a quick look with some actual data.
Vincent
Vincent on 29 Apr 2015
Enclosed is the file containing the structure 'Running' if you want to try. Unfortunately the approach given by James is not working in my case ('Dot name reference on non-scalar structure')

Sign in to comment.

Accepted Answer

Thorsten
Thorsten on 29 Apr 2015
event1LFS = mean(cellfun(@(x) x.SP.LFS2LMS, Running));
  3 Comments
Adam
Adam on 29 Apr 2015
You should be careful what you wish for when you go into something with the sole aim of trying to do something "without a for loop".
It is possible to do all manner of things less efficient than a for loop.
Unfortunately cellfun is often one of them. Personally I like it because I find it tidy, but if pure speed is your aim you should do some proper testing of the speed of different approaches because you will often find that cellfun is slower than a good old for loop.
The simple idea that 'for loops are bad' in Matlab is somewhat dubious. The main idea is that vectorisation is a lot faster than a for loop rather than that a for loop is just absolutely worse than any other conceivable alternative.
Stephen23
Stephen23 on 30 Apr 2015
Edited: Stephen23 on 30 Apr 2015
@Vincent: Code vectorization is applied to numeric arrays, in which case it is very fast. If you have nested cell arrays or structures, then vectorization is no longer relevant, and loops are often the fastest option (with array preallocation). This means how you design your data structure has a big effect on what processing you can do quickly and efficiently.
Note that this is no different to any other programming language: designing your data structure carefully and with consideration to the performance and operation requirements will make the code both simpler and faster. This is no different to any other language, just the choices and features are different...
If speed really is the goal then vectorization is worth it, but it requires keeping the data in numeric arrays: the trick is to think of their dimensions as ways of arranging the data (rather than organizing the data using cells or structures).

Sign in to comment.

More Answers (2)

James Tursa
James Tursa on 29 Apr 2015
Edited: James Tursa on 29 Apr 2015
Try this: EDITED
temp1 = [Running{:}]; % Extract the cells, concatenate into a single struct array
temp2 = [temp1.SP]; % Extract 1st level field and concatenate
event1LFS = mean([temp2.LFS2LMS]); % Extract 2nd level field, concatenate, take mean
  3 Comments
Stephen23
Stephen23 on 29 Apr 2015
Sadly nested structures do not allow the extraction of all field values into a comma separated list, so the [temp.xxx.yyy] syntax does not work.
James Tursa
James Tursa on 29 Apr 2015
Thanks ... that means an extra step. I have edited my Answer to reflect this.

Sign in to comment.


Stephen23
Stephen23 on 29 Apr 2015
Edited: Stephen23 on 1 Sep 2015
You can do this without any loops or cellfun if you rearrange the data a little bit. The following two changes would need to be made:
  1. use a non-scalar structure instead of a cell array holding individual scalar structures.
  2. do not nest structures within other structures.
After these two changes you could simply do this:
mean([Running.LFS2LMS])
which is much faster and more efficient that any playing around with cell arrays and the like. Here is a simple example showing how accessing non-scalar structure can work:
>> A(3).data = 8;
>> A(2).data = 4;
>> A(1).data = 2;
>> mean([A.data])
ans =
4.6667
And that is it: no cell arrays, no functions, no complications... just fast and simple.
  3 Comments
Vincent
Vincent on 29 Apr 2015
Correction. It did not work properly because it takes only the first element of Running...
Stephen23
Stephen23 on 1 Sep 2015
Edited: Stephen23 on 1 Sep 2015
If Running is a non-scalar structure then the syntax
Running.SP
expands it into a comma-separated list, which is equivalent to this:
Running(1).SP,Running(2).SP,Running(3).SP,...
But you only assign the first one to a variable, which is basically the same as doing this:
temp = Running(1).SP
This is why I clearly state in my answer "2. do not nest structures within other structures.".

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!