"Intermediate dot indexing produced a comma-separated list.." error prevents extracting values from nested indexed fields

The following minimum working example illustrates a very common situation in Matlab, and shows the error produced when trying to aggregate values from across indexed fields that are themselves nested within other indexed fields.
a.students(1).grades = [7 8 9];
a.students(2).grades = [6 7 8];
max(a.students(:).grades(:)) % obtain maximum of ALL grades, from ALL students
% gives the error:
% Intermediate dot '.' indexing produced a comma-separated list with 2 values, but it must produce a single value when followed by subsequent indexing operations.
The same error is produced if I simply try to print out those values, without applying max or any other function, and putting the expression in square brackets doesn't help:
[ a.students(:).grades(:) ]
The only way to go around this is to keep using for loops, which makes code inelegant and error-prone. This seems too basic a feature to not have a built-in solution in Matlab. Would appreciate any suggestions how this could be achieved.

1 Kommentar

Your code does not work because you are trying to apply one index onto multiple variables. MATLAB does not have such a command that applies one index to all members of a comma-separated list, nor is it likely to in the near future (that would be a major change in how commas and lists are interpreted).
a.students(1).grades = [7 8 9];
a.students(2).grades = [6 7 8];
a.students(:).grades % this returns multiple separate variables, not one array.
ans = 1×3
7 8 9
ans = 1×3
6 7 8
a.students(:).grades(:) % how can we apply one index to multiple arrays?
Intermediate dot '.' indexing produced a comma-separated list with 2 values, but it must produce a single value when followed by subsequent indexing operations.
Basically your code is doing something a bit like this (pseudo-code):
[7 8 9],[6 7 8](:)
with the expectation that the colon index would be applied to both members of the comma-separated list.

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

If you want the max over all of the grades you can do it very simply like this
val = max([a.students.grades])

6 Kommentare

Note
>> [a.students.grades]
ans =
7 8 9 6 7 8
+1 Note that this approach will work only when all parent structures are scalar (as in the given example: a is scalar, students is non-scalar). If any of the parent structures are non-scalar, then intermediate variables will be required.
@Stephen23 Good point. I see that now.
So extending the OP's question suppose we had
a(1).students(1).grades = [7 8 9];
a(1).students(2).grades = [6 7 8];
a(2).students(1).grades = [1 2 3];
a(2).students(2).grades = [4 5 6];
So now the parent variable a is not a scalar. What would be a good way of getting all of the grades into a single vector, so that we could then find for example the overall maximum?
Assuming compatible sizes and classes:
a(1).students(1).grades = [7 8 9];
a(1).students(2).grades = [6 7 8];
a(2).students(1).grades = [1 2 3];
a(2).students(2).grades = [4 5 6];
tmp = [a.students];
max([tmp.grades])
ans = 9
OK thanks for the example that helps me understand better. At least for me it is a little subtle, but this makes sense.
Thanks a lot Jon and Stephen. So strange that I had already thought of putting the expression in square brackets, but because I had also included the (:), that prompted the error. Also, using my MWE, the error I get now is different from the one in the thread title,namely the related one "Expected one output from a curly brace ..."
Anyway, I've learned something from this, thank you.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Kategorien

Produkte

Version

R2022a

Gefragt:

am 18 Mai 2022

Kommentiert:

am 3 Nov. 2022

Community Treasure Hunt

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

Start Hunting!

Translated by