Design choice for iterating over a cell array

조회 수: 128 (최근 30일)
Alec Poulin
Alec Poulin 2018년 3월 27일
댓글: J. Alex Lee 2018년 8월 9일
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