Is there a foreach in MATLAB? If so, how does it behave if the underlying data changes?

MatlabSyntax

Matlab Problem Overview


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)?

Matlab Solutions


Solution 1 - Matlab

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 - Matlab

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 - Matlab

The MATLAB for loop basically allows huge flexibility, including the [tag: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 - Matlab

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 - Matlab

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

Solution 6 - Matlab

When iterating over cell arrays of strings, the loop variable (let's call it f) becomes a single-element cell array. Having to write f{1} everywhere gets tedious, and modifying the loop variable provides a clean workaround.

% This example transposes each field of a struct.
s.a = 1:3;
s.b = zeros(2,3);
s % a: [1 2 3]; b: [2x3 double]
for f = fieldnames(s)'
    s.(f{1}) = s.(f{1})';
end
s % a: [3x1 double]; b: [3x2 double]

% Redefining f simplifies the indexing.
for f = fieldnames(s)'
    f = f{1};
    s.(f) = s.(f)';
end
s % back to a: [1 2 3]; b: [2x3 double]

Solution 7 - Matlab

Let's say you have an array of data:

n = [1    2   3   4   6   12  18  51  69  81  ]

then you can 'foreach' it like this:

for i = n, i, end

This will echo every element in n (but replacing the i with more interesting stuff is also possible of course!)

Solution 8 - Matlab

I think this is what the OP really wants:

array = -1:0.1:10

for i=1:numel(array)
    disp(array(i))
end

Solution 9 - Matlab

As of today (Feb 27), there is a new For-Each toolbox on the MATLAB File Exchange that accomplishes the concept of foreach. foreach is not a part of the MATLAB language but use of this toolbox gives us the ability to emulate what foreach would do.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKipView Question on Stackoverflow
Solution 1 - MatlabZach ScrivenaView Answer on Stackoverflow
Solution 2 - MatlabMr FoozView Answer on Stackoverflow
Solution 3 - MatlabBHFView Answer on Stackoverflow
Solution 4 - MatlabLorenView Answer on Stackoverflow
Solution 5 - MatlabJason SView Answer on Stackoverflow
Solution 6 - MatlabekornView Answer on Stackoverflow
Solution 7 - MatlabSkidderView Answer on Stackoverflow
Solution 8 - MatlabtirthView Answer on Stackoverflow
Solution 9 - MatlabDang KhoaView Answer on Stackoverflow