31 votes

Comment puis-je obtenir un tableau paresseux en Ruby?

Comment puis-je obtenir un tableau paresseux en Ruby ?

En Haskell, je peux parler de [1..], qui est une liste infinie, générée de manière paresseuse au fur et à mesure des besoins. Je peux aussi faire des choses comme iterate (+2) 0, qui applique n'importe quelle fonction que je lui donne pour générer une liste paresseuse. Dans ce cas, cela me donnerait tous les nombres pairs.

Je suis sûr que je peux faire de telles choses en Ruby, mais je n'arrive pas à comprendre comment.

1voto

sepp2k Points 157757

Comme je l'ai déjà dit dans mes commentaires, mettre en œuvre une telle chose que des tableaux paresseux ne serait pas judicieux.

L'utilisation de Enumerable peut fonctionner agréablement dans certaines situations, mais diffère des listes paresseuses sur certains points : des méthodes comme map et filter ne seront pas évaluées de manière paresseuse (donc elles ne fonctionneront pas sur des enumérables infinies) et les éléments qui ont été calculés une fois ne sont pas stockés, donc si vous accédez à un élément deux fois, il est calculé deux fois.

Si vous voulez le comportement exact des listes paresseuses de Haskell en Ruby, il existe une gemme lazylist qui implémente des listes paresseuses.

1voto

steenslag Points 29662

Cela bouclera à l'infini :

0.step{|i| puts i}

Cela bouclera à l'infini deux fois plus rapidement :

0.step(nil, 2){|i| puts i}

Cela ira à l'infini, seulement si vous le souhaitez (résultat dans un énumérateur).

table_of_3 = 0.step(nil, 3)

0voto

Donato Points 1745

La bonne réponse a déjà identifié la méthode "lazy", mais l'exemple fourni n'était pas trop utile. Je vais donner un meilleur exemple de quand il est approprié d'utiliser lazy avec des tableaux. Comme indiqué, lazy est défini en tant que méthode d'instance du module Enumerable, et il fonctionne sur DES objets qui implémentent le module Enumerable (par exemple les tableaux - [].lazy) ou des énumérateurs qui sont la valeur de retour des itérateurs dans le module énumerable (par exemple each_slice - [].each_slice(2).lazy). Notez que dans le module Enumerable, certaines des méthodes d'instance renvoient des valeurs plus primitives comme true ou false, d'autres renvoient des collections comme les tableaux et d'autres renvoient des énumérateurs. Certains renvoient des énumérateurs si aucun bloc n'est donné.

Mais pour notre exemple, la classe IO a également un itérateur each_line, qui renvoie un énumérateur et peut donc être utilisé avec "lazy". La belle chose à propos du renvoi d'un énumérateur est qu'il ne charge pas réellement la collection (par exemple un grand tableau) en mémoire sur lequel il travaille. Au lieu de cela, il a un pointeur vers la collection et stocke ensuite l'algorithme (par exemple each_slice(2)) qu'il utilisera sur cette collection, lorsque vous souhaitez traiter la collection avec quelque chose comme to_a, par exemple.

Donc, si vous travaillez avec un énumérateur pour un énorme gain de performance, vous pouvez maintenant attacher lazy à l'énumérateur. Ainsi, au lieu de parcourir toute une collection pour mettre en correspondance cette condition :

file.each_line.select { |line| line.size == 5 }.first(5)

Vous pouvez invoquer lazy:

file.each_line.lazy.select { |line| line.size == 5 }.first(5)

Si nous analysons un grand fichier texte pour les 5 premières correspondances, une fois les 5 correspondances trouvées, il n'est plus nécessaire de poursuivre l'exécution. D'où la puissance de lazy avec n'importe quel type d'objet énumérable.

-4voto

carlfilips Points 1485

Les tableaux Ruby se développent dynamiquement au besoin. Vous pouvez leur appliquer des blocs pour renvoyer des choses comme des nombres pairs.

array = []
array.size # => 0
array[0] # => nil
array[9999] # => nil
array << 1
array.size # => 1
array << 2 << 3 << 4
array.size # => 4

array = (0..9).to_a
array.select do |e|
  e % 2 == 0
end

# => [0,2,4,6,8]

Cela aide-t-il?

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