Design choice for iterating over a cell array

125 次查看(过去 30 天)
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?
  1 个评论
Stephen23
Stephen23 2018-3-27
编辑:Stephen23 2018-3-27

"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
Philip Borghesani 2018-3-27
编辑:Philip Borghesani 2018-3-28
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]}
  3 个评论
J. Alex Lee
J. Alex Lee 2018-8-9
Interesting tidbit...is this a vestige of the row-oriented array definition of Matlab, so that the concept of iterating through a default 1D array worked as intended? (I was always curious why the syntax failed for iterating through column vectors, and now I know!)
Other than for intuition based on the 1D row vector, is it more generally useful to define "for" this way? For "consistency", this works for multidimensional arrays, but doesn't it seem completely arbitrary to choose to iterate on the 2nd dimension?
Another way in which this "consistency" argument violates my intuition is that being allowed to use linear indexing of arrays suggests to me that "for" would iterate on the linear index of an array.
If you wanted to iterate on the linear index, you might think you can do
X = rand(2,3,4)
for x in X(:)
x
end
but of course this returns a column vector, so you would have to first transpose to get what you want...for full consistency, shouldn't the (:) construct return a row so that "all elements" is equivalent to "all columns"?
J. Alex Lee
J. Alex Lee 2018-8-9
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)

请先登录,再进行评论。

更多回答(1 个)

Bob Thompson
Bob Thompson 2018-3-27
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.
  4 个评论
Stephen23
Stephen23 2018-3-27
@Bob Nbob: it is allowed to redefine the index. Pay attention to the warning messages though: the editor will offer to hide the warning for that line.
Rik
Rik 2018-3-27

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.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Loops and Conditional Statements 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by