177 votes

Existe-t-il un foreach dans MATLAB ? Si oui, comment se comporte-t-il si les données sous-jacentes changent ?

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

150voto

Zach Scrivena Points 15052

Les fonctionnalités de MATLAB POUR est statique par nature ; vous ne pouvez pas modifier la variable de la boucle entre les itérations, contrairement à la boucle pour(initialisation;condition;incrément) Structure de boucle 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 être en mesure de répondre aux modifications apportées à la structure des données au cours des itérations, une fonction WHILE boucle 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 la boucle comme vous le souhaitez :

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

Btw, le pour-each boucle en Java (et peut-être d'autres langages) produit un comportement non spécifié lorsque la structure de données est modifiée pendant l'itération. Si vous avez besoin de modifier la structure de données, vous devez utiliser une méthode appropriée pour modifier la structure de données. Itérateur qui permet l'ajout et la suppression d'éléments dans la collection que vous itérez. La bonne nouvelle est que MATLAB prend en charge les objets Java, ce qui vous permet de 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

1 votes

Si B est indéfini, votre premier exemple n'imprime pas 1-5. Il imprime Undefined function or variable 'B' .

3 votes

Pour le 1er exemple, assurez-vous que A est un vecteur ligne et non un vecteur colonne. Si A est une matrice, chaque k sera un vecteur colonne de cette matrice. Ainsi, la transposition( A' ) ou vectoriser ( A(:)' ) si nécessaire.

3 votes

-1 Je le fais no Je pense que le code de type Java devrait être votre premier choix pour travailler avec Matlab en .m des fichiers.

92voto

Mr Fooz Points 21092

Zach a raison en ce qui concerne la réponse directe à la question.

Une note latérale intéressante est que les deux boucles suivantes ne s'exécutent pas de la même manière :

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 l'itère 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 10k éléments, puis il parcourt tous les éléments du tableau.

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 d'allouer une mémoire infinie). Voir Le blog de Loren pour les détails.

Notez également que vous pouvez itérer sur des tableaux de cellules.

2 votes

Oui, j'ai été surpris de cela quand je l'ai rencontré. Cette optimisation des tableaux a en fait lieu à de nombreux endroits. Si vous utilisez la notation entre parenthèses, vous verrez parfois des avertissements de performance dans l'éditeur Matlab vous indiquant qu'il pense pouvoir optimiser l'allocation des tableaux si vous le laissez faire.

0 votes

J'ai entendu dire que Matlab a une évaluation paresseuse maintenant. Si ce n'est pas le cas, nous disposons de la technologie pour les mettre en œuvre.

20voto

BHF Points 489

Le programme MATLAB pour La boucle permet essentiellement une grande flexibilité, y compris la foreach fonctionnalité. Voici quelques exemples :

1) Définir l'index de début, d'incrémentation et de fin.

for test = 1:3:9
   test
end

2) Boucle sur le vecteur

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

3) Boucle sur la 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

4 votes

Avec le tableau de cellules, notez qu'il itérera sur les colonnes de la matrice de cellules.

18voto

Loren Points 1182

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

0 votes

Cependant, d'après mon expérience, je dirais que leurs performances sont égales ou pires que celles de l'écriture d'une boucle for, mais qu'elles sont plus belles, et qui sait, elles pourraient s'améliorer à l'avenir.

15voto

Jason S Points 58434

Ooh ! bonne question.

La boucle for de Matlab prend une matrice en entrée et itère sur ses colonnes. Matlab gère aussi pratiquement tout par valeur (pas de passage par référence). Je m'attendrais donc à ce qu'il prenne un instantané de l'entrée de la boucle for afin qu'elle soit 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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X