Is there a foreach in MATLAB? If so, how does it behave if the underlying data changes?
Solution 1
MATLAB's FOR loop is static in nature; you cannot modify the loop variable between iterations, unlike the for(initialization;condition;increment) loop structure in other languages. This means that the following code always prints 1, 2, 3, 4, 5 regardless of the value of B.
A = 1:5;
for i = A
A = B;
disp(i);
end
If you want to be able to respond to changes in the data structure during iterations, a WHILE loop may be more appropriate --- you'll be able to test the loop condition at every iteration, and set the value of the loop variable(s) as you wish:
n = 10;
f = n;
while n > 1
n = n-1;
f = f*n;
end
disp(['n! = ' num2str(f)])
Btw, the for-each loop in Java (and possibly other languages) produces unspecified behavior when the data structure is modified during iteration. If you need to modify the data structure, you should use an appropriate Iterator instance which allows the addition and removal of elements in the collection you are iterating. The good news is that MATLAB supports Java objects, so you can do something like this:
A = java.util.ArrayList();
A.add(1);
A.add(2);
A.add(3);
A.add(4);
A.add(5);
itr = A.listIterator();
while itr.hasNext()
k = itr.next();
disp(k);
% modify data structure while iterating
itr.remove();
itr.add(k);
end
Solution 2
Zach is correct about the direct answer to the question.
An interesting side note is that the following two loops do not execute the same:
for i=1:10000
% do something
end
for i=[1:10000]
% do something
end
The first loop creates a variable i
that is a scalar and it iterates it like a C for loop. Note that if you modify i
in the loop body, the modified value will be ignored, as Zach says. In the second case, Matlab creates a 10k-element array, then it walks all elements of the array.
What this means is that
for i=1:inf
% do something
end
works, but
for i=[1:inf]
% do something
end
does not (because this one would require allocating infinite memory). See Loren's blog for details.
Also note that you can iterate over cell arrays.
Solution 3
The MATLAB for loop basically allows huge flexibility, including the foreach functionality. Here some examples:
1) Define start, increment and end index
for test = 1:3:9
test
end
2) Loop over vector
for test = [1, 3, 4]
test
end
3) Loop over string
for test = 'hello'
test
end
4) Loop over a one-dimensional cell array
for test = {'hello', 42, datestr(now) ,1:3}
test
end
5) Loop over a two-dimensional cell array
for test = {'hello',42,datestr(now) ; 'world',43,datestr(now+1)}
test(1)
test(2)
disp('---')
end
6) Use fieldnames of structure arrays
s.a = 1:3 ; s.b = 10 ;
for test = fieldnames(s)'
s.(cell2mat(test))
end
Solution 4
If you are trying to loop over a cell array and apply something to each element in the cell, check out cellfun
. There's also arrayfun
, bsxfun
, and structfun
which may simplify your program.
Solution 5
ooh! neat question.
Matlab's for loop takes a matrix as input and iterates over its columns. Matlab also handles practically everything by value (no pass-by-reference) so I would expect that it takes a snapshot of the for-loop's input so it's immutable.
here's an example which may help illustrate:
>> A = zeros(4); A(:) = 1:16
A =
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
>> i = 1; for col = A; disp(col'); A(:,i) = i; i = i + 1; end;
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
>> A
A =
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
Related videos on Youtube
Kip
I've been programming since I got my hands on a TI-83 in precalculus class during junior year of high school. Some cool stuff I've done: Chord-o-matic Chord Player: find out what those crazy chords are named! Everytime: keep track of the current time in lots of time zones from your system tray BigFraction: open source Java library for handling fractions to arbitrary precision. JSON Formatter: a completely client-side JSON beautifier/uglifier. QuickReplace: a completely client-side regex tool. It's behind some ugly developer UI since I created it for myself to use. (Sorry not sorry.)
Updated on October 04, 2020Comments
-
Kip over 3 years
Is there a foreach structure in MATLAB? If so, what happens if the underlying data changes (i.e. if objects are added to the set)?
-
Mr Fooz over 15 yearsYeah, I was surprised about this when I ran into it. This optimization of arrays actually takes place in many places. If you use bracket notation, sometimes you'll see performance warnings in the Matlab editor telling you it thinks it can optimize out the array allocation if you let it.
-
Kleist over 12 yearsThat just prints 10 since
numel(array)
is the number of elements in array. perhaps you meant1:numel(array)
? -
Kleist over 12 yearsIf B is undefined, your first example doesn't print 1-5. It prints
Undefined function or variable 'B'
. -
yuk over 12 yearsFor the 1st example make sure that
A
is a row vector, not column vector. IfA
is a matrix, each k will be a column vector from that matrix. So, transpose(A'
) or vectorize (A(:)'
) if needed. -
Admin about 12 yearsthough, from experience I would say that their performance is equal or worst to writing a for-loop, better looking though, and who knows they might improve in the future.
-
bobobobo over 11 years-1 I do not think Java-like code should be your first choice way to work with Matlab in
.m
files. -
Oriol over 10 yearsWouldn't
for i = -1:0.1:10; disp(i); end;
be better ? -
Evgeni Sergeev over 10 yearsWith the cell array, take note that it will iterate over columns of the cell array.
-
Dmytro over 7 yearsgreetings from the future; we come with plenty of solutions to iterator invalidation problem.
-
Dmytro over 7 yearsI hear Matlab has lazy evaluation now. If not, we do have the technology to implement them.