Skip to content

Instantly share code, notes, and snippets.

@ffmpbgrnn
Created October 29, 2015 19:36
Show Gist options
  • Save ffmpbgrnn/cdf892ae9cf192ca1aeb to your computer and use it in GitHub Desktop.
Save ffmpbgrnn/cdf892ae9cf192ca1aeb to your computer and use it in GitHub Desktop.
MATLAB for Loops Iterate Over Columns, Not Elements

MATLAB's for loop iterates over columns, not individual elements. I've tripped over this too many times.

Consider a matrix.

A = magic(3)

A = ...

     8     1     6
     3     5     7
     4     9     2

for col = A
    disp(col)
end

     8
     3
     4

     1
     5
     9

     6
     7
     2

This is noticeable and not too sinister with a square matrix. In fact, from a purely matrix-centric point of view this makes sense.

Apply To Dynamic Structure References

However, suppose you're working with an N x 1 element of some sort; and you've got other things on your mind. For example, you want to iterate over fields of a struct.

some_struct = ...

    field1: 'Value of field 1'
    field2: 'Value of field 2'
    field3: 'Value of field 3'

fnames = fieldnames(some_struct)

    'field1'
    'field2'
    'field3'

If you have a column vector or cell array, you get one iteration. In that iteration, your iteration variable is the entire column.

for name = fnames
    some_struct.(name)
end

Error: 'Argument to dynamic structure reference must evaluate to a valid field name.'

What? That error message never comes with a line number by the way.

for name = fnames
    disp(name)
end

    'field1'
    'field2'
    'field3'

Of course. We iterate only once. The prior loop tried to access a struct field with an entire column of values. So you must loop over the transpose of the column.

for Loops Over Cell Arrays Don't Work Like Cell References

Now try and use a dynamic structure reference within the loop.

for name = fieldnames(some_struct)'
    some_struct.(name)
end

Error: 'Argument to dynamic structure reference must evaluate to a valid field name.'

Hang on. The same error? The extra trick is that name is actually a 1 x 1 cell array. It needs to be a string to work as a dynamic structure reference.

fnames = fieldnames(some_struct);
for name = fnames'
    disp(some_struct.(char(name)))
end

'Value of field 1'
'Value of field 2'
'Value of field 3'

Why on Earth is name a cell array, when fname{1} is a char array? I'm not sure, but I'm in pain thinking about it. 😭

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment