web-dev-qa-db-fra.com

Existe-t-il une foreach dans MATLAB? Si tel est le cas, comment se comporte-t-il si les données sous-jacentes changent?

Existe-t-il une structure foreach dans MATLAB? Si tel est le cas, que se passe-t-il si les données sous-jacentes changent (c'est-à-dire si des objets sont ajoutés à l'ensemble)?

164
Kip

La boucle MATLAB [~ # ~] pour [~ # ~] est de nature statique; vous ne pouvez pas modifier la variable de boucle entre les itérations, contrairement à la structure de boucle pour (initialisation; condition; incrément) dans d'autres langues. Cela signifie que le code suivant imprime toujours 1, 2, 3, 4, 5 quelle que soit la valeur de B.

A = 1:5;

for i = A
    A = B;
    disp(i);
end

Si vous voulez pouvoir répondre aux modifications de la structure de données lors des itérations, un [~ # ~] tant que [~ # ~] loop peut-être plus approprié --- vous pourrez tester la condition de la boucle à chaque itération et définir la valeur de la ou des variables de boucle à votre guise:

n = 10;
f = n;
while n > 1
    n = n-1;
    f = f*n;
end
disp(['n! = ' num2str(f)])

Btw, la boucle pour-each en Java (et éventuellement d'autres langages) produit un comportement non spécifié lorsque la structure de données est modifiée au cours de itération. Si vous devez modifier la structure de données, vous devez utiliser une instance appropriée Iterator qui permet d'ajouter et de supprimer des éléments dans la collection que vous parcourez. La bonne nouvelle est que MATLAB supporte les objets Java, vous pouvez donc faire quelque chose comme ceci:

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
144
Zach Scrivena

Zach a raison sur la réponse directe à la question.

Il est intéressant de noter que les deux boucles suivantes n’exécutent pas la même chose:

for i=1:10000
  % do something
end
for i=[1:10000]
  % do something
end

La première boucle crée une variable i qui est un scalaire et la répète comme une boucle C for. Notez que si vous modifiez i dans le corps de la boucle, la valeur modifiée sera ignorée, comme le dit Zach. Dans le second cas, Matlab crée un tableau de 10 000 éléments, puis parcourt tous les éléments du tableau.

Qu'est-ce que cela signifie, c'est que

for i=1:inf
  % do something
end

fonctionne, mais

for i=[1:inf]
  % do something
end

ne le fait pas (car celui-ci nécessiterait l'allocation de mémoire infinie). Voir blog de Loren pour plus de détails.

Notez également que vous pouvez effectuer une itération sur des tableaux de cellules.

88
Mr Fooz

La boucle MATLAB for permet une grande flexibilité, y compris la fonctionnalité foreach . Voici quelques exemples:

1) Définir les index de début, d’incrément et de fin

for test = 1:3:9
   test
end

2) boucle sur vecteur

for test = [1, 3, 4]
   test
end

3) boucle sur chaîne

for test = 'hello'
   test
end

4) Boucle sur un tableau de cellules unidimensionnel

for test = {'hello', 42, datestr(now) ,1:3}
   test
end

5) Boucle sur un tableau de cellules à deux dimensions

for test = {'hello',42,datestr(now) ; 'world',43,datestr(now+1)}
   test(1)   
   test(2)
   disp('---')
end

6) Utiliser les noms de champs des tableaux de structure

s.a = 1:3 ; s.b = 10  ; 
for test = fieldnames(s)'
   s.(cell2mat(test))
end
18
BHF

Si vous essayez de boucler sur un tableau de cellules et d'appliquer quelque chose à chaque élément de la cellule, consultez cellfun. Il y a aussi arrayfun, bsxfun et structfun qui peuvent simplifier votre programme.

17
Loren

ooh! question soignée.

La boucle for de Matlab prend une matrice en entrée et itère sur ses colonnes. Matlab gère également pratiquement tout par valeur (pas de référence par référence), donc je suppose qu’il prend un instantané de l’entrée de la boucle for, il est donc immuable.

voici un exemple qui peut aider à illustrer:

>> 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
14
Jason S

Lors de l'itération sur des tableaux de chaînes de chaînes de cellules, la variable de boucle (appelons-la f) devient un tableau de cellules à un seul élément. Devoir écrire f{1} partout devient fastidieux et la modification de la variable de boucle fournit une solution de contournement propre.

% 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]
7
ekorn

Disons que vous avez un tableau de données:

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

alors vous pouvez "foreach" comme ça:

for i = n, i, end

Cela fera écho à chaque élément de n (mais remplacer i par des éléments plus intéressants est également possible!)

5
Skidder

Je pense que c’est ce que le PO veut vraiment:

array = -1:0.1:10

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

À compter d’aujourd’hui (27 février), il existe une nouvelle boîte à outils For-Each sur l’échange de fichiers MATLAB , qui concrétise le concept de foreach. foreach ne fait pas partie du langage MATLAB, mais l'utilisation de cette boîte à outils nous permet d'émuler ce que foreach ferait.

4
Dang Khoa