2

I thought that if I write

for x = cell_array
    ...
end

then the loop will run over the elements of cell_array, but in the following case it doesn't:

>> tags

tags = 

    'dset3'
    'dset4'
    'cpl1'

>> class(tags)

ans =

cell

>> for t = tags
     tmp = t{:}  %No semicolon: i.e. print it.
   end

tmp =

dset3

So it only works for the first element.

What's the problem?

6
  • If you read the answers to the duplicate you might learn what you're doing wrong. There are many examples of the proper use of a cell array there and the two answers here are pretty much duplicated there. Commented Feb 7, 2014 at 17:55
  • @horchler My answer here explains the key to the confusion, which was the behaviour of the {:} expansion for single-column cell arrays. The other question doesn't mention that (no appearance of {:} on that page). Commented Feb 7, 2014 at 21:17
  • 1
    for x = [cell_array{:}]; disp(x); end Commented Aug 18, 2015 at 15:17
  • @user66081 The above doesn't work for e.g. cell_array = {eye(1), eye(2)}. Because it's trying to concat the arrays, resulting in Error using horzcat Dimensions of matrices being concatenated are not consistent. But this is good for well-behaved cell arrays, especially those that could have been plain matrices anyway. Commented Aug 21, 2015 at 10:34
  • 1
    This really shouldn't be marked duplicate. The other question asks what happens when you try to modify the iteration range at runtime. This question here is related to understanding cell expansion and whether iterations work over columns vs rows. Even if the answers happen to have some similarity, they are very different questions. Commented Nov 6, 2015 at 20:50

2 Answers 2

9

According to the documentation, for x = cell_array will iterate over columns of the cell array.

The reason for the confusion in the question is to do with how the {:} expansion behaves:

>> a = {3;4}

a = 

    [3]
    [4]

>> b = a{:}

b =

     3

In the above, a{:} does something akin to typing in a comma-separated list where the elements are the elements of the cell array a. Except not quite! If we write such a list explicitly, we get:

>> c = 3,4

c =

     3


ans =

     4

Somehow, with the >> b = a{:}, the other elements of a are discarded silently, even if e.g. a = {1 2; 3 4}.

However, in other contexts, a{:} will expand into the full comma-separated list:

>> extra_args = {'*-'; 'linewidth'; 30};
>> plot(1:2, extra_args{:})
>> extra_args = {};
>> plot(1:2, extra_args{:})

This will do what it's intended to do.

Sign up to request clarification or add additional context in comments.

1 Comment

Interestingly, it doesn't just expand into a comma-separated list. If a={}, then fprintf('%s %s\n', a{:}, 'b', 'c') works, but fprintf('%s %s\n', , 'b', 'c') doesn't. I checked, and this also applies to user-created functions, so it's a feature of the language, rather than special processing done by the function fprintf.
2

There is a nice function built into Matlab called cellfun. It allows you to "do something" with every element in the array in turn - regardless of its shape.

For example:

cellfun(@(x)fprintf(1,'%s',x), cellArray);

will loop over cellArray, and print the string in each cell.

You can also do one of the following things:

for x = cellArray(:)

  % do stuff to x

end

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.