Design choice for iterating over a cell array

197 views (last 30 days)
Alec Poulin on 27 Mar 2018
Commented: J. Alex Lee on 9 Aug 2018
I discovered that it was possible to iterate over a cell array in Matlab:
for x = {1, "foo", [1,2]}
x
end
However, for each iteration, x is a 1x1 cell array containing an element of the cell array over which we iterate, instead of (as it would be logical) directly the element of the cell array. I.e., x takes the values {1}, {"foo"}, {[1,2]}, instead of 1, "foo", [1,2]. It is a bit cumbersome to have to call x{1} each time I want to use the value from the cell array, instead of simply typing x.
Is there any good reason why the language was designed this way?
Stephen23 on 27 Mar 2018
Edited: Stephen23 on 27 Mar 2018

"Is there any good reason why the language was designed this way?"

Consistency. All arrays can be iterated over, and for all arrays the index variable is one element (or one column) of that array, no matter what class. People often forget that for actually loops over the columns, which would lead to awkward bugs/inconsistencies/... if the contents of cell arrays were returned in the index.

Philip Borghesani on 27 Mar 2018
Edited: Philip Borghesani on 28 Mar 2018
There was not much choice in how the language could do it. For was initially defined to loop over the columns of the input matrix. Examine these two lines of code and think about what would happen if the for loop tried to dereference the cell.
>> for x=[1,2;4,5],x,end
x =
1
4
x =
2
5
>> for x={1,2;4,5};x,end
x =
2×1 cell array
{[1]}
{[4]}
x =
2×1 cell array
{[2]}
{[5]}
J. Alex Lee on 9 Aug 2018
And to the point about string(array)s, they are a welcome data type to Matlab for other reasons, but most Matlab functions and methods that return lists of non-numeric things that one might want to iterate through in a cell array of characters rather than a string array...and they return these "lists" in columns (I just found that sometimes it returns rows to add to my confusion, e.g., the keys in a containers.Map). To Alec's point, there are still cumbersome coding adjustments to get what you want, e.g.
for prop = transpose(string(properties(myclass)))
prop
end
or working with an intermediary integer index
myprops = properties(myclass);
for i = 1:numel(myprops)
prop = myprops(i);
end
For a specific use case that I imagine isn't that uncommon, iterating through containers.Map entries is bulky one way or another because you either have to convert to string to iterate nicely and convert back to char to access the map contents, or convert the 1x1 cell to char (or append the {1}, which I think is semantically ugly)

Bob Thompson on 27 Mar 2018
I can't really speak to why the language was designed in that manner, but I can say that there are times where you want to consider the cell as a whole, rather than just the contents, and the specific value of x that you are calling has been written to call the cell as a whole.
Additionally, you will want to leave it in this manner, because you have different classes of data contained within your cells. If you attempted to assign x as the contents of the cell, rather than the cell itself, you would receive an error after your first iteration because you would be attempting to assign a string class value to a double class variable. Leaving x as a cell, and requiring the calling of the contents, allows you to switch smoothly between class types within the cell.
Rik on 27 Mar 2018

Is that a setting buried somewhere deep? Because for me it doesn't offer to hide the warning, it just suggests it as a possible course of action.

Categories

Find more on Multidimensional Arrays in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!