2 votes

array.each fonctionnera-t-il correctement si le tableau est mis à jour à chaque itération ?

La méthode permettant de traiter chaque élément d'un tableau le fera-t-elle correctement si le tableau est mis à jour dans le bloc de code de la boucle each ?

Par exemple :

arr.each do |x|
  if (x != 2)
    arr.push(x+4)
  end
end

La boucle va-t-elle continuer à itérer sur chaque élément du tableau, même si celui-ci est allongé ?

4voto

DigitalRoss Points 80400

Peut-être


Oui si vous parlez de _IRM ,_ et la question est : " L'itérateur va-t-il parcourir mes nouveaux éléments ? ".

Si vous parlez de Ruby en tant que langage, " peut-être ". Comme il n'y a pas de spécification, l'IRM sert d'implémentation de référence.

Cela dit, cela semble être quelque chose qui serait spécifique à l'implémentation, en partie parce qu'exiger un comportement spécifique imposerait une contrainte aux implémentations sans bénéfice clair, mais avec certains compromis de performance.

C'est aussi un peu _impératif ,_ donc ce n'est peut-être pas "la manière Ruby", qui penche plus vers _les styles fonctionnels ._

Voici comment je pense qu'un bon programme Ruby devrait écrire ce genre de boucle. Cette expression renvoie l'ancien tableau a sauf s'il change, auquel cas elle crée un nouveau tableau dans un style fonctionnel afin qu'il n'y ait jamais de doute sur ce que sera le résultat...

>> a = [1, 2, 3]
=> [1, 2, 3]
>> a.inject(a) { |m, e| e < 99 ? m + [99] : m }
=> [1, 2, 3, 99, 99, 99]

Une expression semi-fonctionnelle plus rapide (si beaucoup de nouveaux éléments sont ajoutés) serait :

t = a.inject(a.dup) { |m, e| e < 99 ? m << 99 : m }

0voto

DanneManne Points 13408

Oui, il continuera à tourner en boucle jusqu'à ce qu'il atteigne la fin du tableau, ce qui n'arrivera probablement jamais puisqu'il reçoit de nouvelles entrées à chaque itération.

Je vous conseille donc fortement de ne pas utiliser votre code actuel, car vous serez probablement bloqué dans une boucle infinie.

Je ne sais pas exactement où vous voulez en venir, mais ce code serait bien meilleur puisqu'il a une fin claire :

arr.each do |x|
  if x < 2
    arr.push x + 4
  end
end

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