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

StackOverflow https://stackoverflow.com/questions/408080

  •  03-07-2019
  •  | 
  •  

Question

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.-à-d. Si des objets sont ajoutés à l'ensemble)?

Était-ce utile?

La solution

La boucle

de FOR de MATLAB 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 souhaitez pouvoir réagir aux modifications de la structure de données lors des itérations, Boucle WHILE peut être plus approprié - vous pourrez tester la condition de la boucle à chaque itération et définir la valeur de la variable de la boucle (s). ) comme vous le souhaitez:

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

Btw, la boucle de chaque 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 l'itération. Si vous devez modifier la structure de données, vous devez utiliser un "noreferrer"> Iterator , qui permet l'ajout et la suppression d'éléments de la collection que vous effectuez une itération. La bonne nouvelle est que MATLAB prend en charge 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

Autres conseils

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

Une note latérale intéressante est 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.

Cela signifie 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 le blog de Loren pour plus de détails.

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

La boucle MATLAB pour offre une grande flexibilité, notamment: la fonctionnalité . 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 réseau 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

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

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). Je suppose donc 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

Lors de l'itération sur des tableaux de cellules de chaînes, 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 sans problème.

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

Disons que vous avez un tableau de données:

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

alors vous pouvez le "foreach" comme ça:

for i = n, i, end

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

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

À compter d’aujourd’hui (27 février), , un nouveau For -Chaque boîte à outils de MATLAB File Exchange qui réalise le concept de pour chaque . foreach ne fait pas partie du langage MATLAB, mais l'utilisation de cette boîte à outils nous permet d'émuler ce que foreach ferait.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top