148 votes

Besoin d'une explication simple de la méthode d'injection

[1, 2, 3, 4].inject(0) { |result, element| result + element } # => 10

Je regarde ce code mais mon cerveau n'enregistre pas comment le nombre 10 peut devenir le résultat. Quelqu'un pourrait-il m'expliquer ce qui se passe ici ?

2voto

Andrew Grimm Points 22996

Ce code n'autorise pas la possibilité de ne pas passer de valeur de départ, mais peut aider à expliquer ce qui se passe.

def incomplete_inject(enumerable, result)
  enumerable.each do |item|
    result = yield(result, item)
  end
  result
end

incomplete_inject([1,2,3,4], 0) {|result, item| result + item} # => 10

2voto

動靜能量 Points 33008

Il s'agit d'une explication simple et assez facile à comprendre :

Oubliez la "valeur initiale", car elle est quelque peu déroutante au début.

> [1,2,3,4].inject{|a,b| a+b}
=> 10

Vous pouvez comprendre ce qui précède comme : J'injecte une "machine à additionner" entre 1,2,3,4. Autrement dit, c'est 1 2 3 4 et c'est une machine à additionner, donc c'est la même chose que 1 + 2 + 3 + 4, et c'est 10.

Vous pouvez en fait injecter un + entre eux :

> [1,2,3,4].inject(:+)
=> 10

et c'est comme, injecter un + entre 1,2,3,4, ce qui fait 1 + 2 + 3 + 4 et donne 10. Le site :+ est la façon dont Ruby spécifie + sous la forme d'un symbole.

C'est assez facile à comprendre et intuitif. Et si vous voulez analyser le fonctionnement étape par étape, c'est comme si vous preniez 1 et 2, et que vous les additionniez, et que lorsque vous obteniez un résultat, vous le stockiez d'abord (c'est-à-dire 3), et ensuite la valeur stockée 3 et l'élément du tableau 3 passant par le processus a + b, qui est 6, et maintenant vous stockez cette valeur, et maintenant 6 et 4 passent par le processus a + b, et sont 10. Vous faites essentiellement

((1 + 2) + 3) + 4

et est de 10. La "valeur initiale" 0 n'est qu'une "base" pour commencer. Dans de nombreux cas, vous n'en avez pas besoin. Imaginez que vous ayez besoin de 1 * 2 * 3 * 4 et que ce soit

[1,2,3,4].inject(:*)
=> 24

et c'est fait. Vous n'avez pas besoin d'une "valeur initiale" de 1 de multiplier le tout avec 1 . Cette fois, il fait

(((1 * 2) * 3) * 4)

et vous obtenez le même résultat que

1 * 2 * 3 * 4

1voto

Douglas G. Allen Points 359

Commencez ici et passez ensuite en revue toutes les méthodes qui prennent des blocs. http://ruby-doc.org/core-2.3.3/Enumerable.html#method-i-inject

Est-ce le bloc qui vous perturbe ou la raison pour laquelle vous avez une valeur dans la méthode ? Bonne question cependant. Quelle est la méthode de l'opérateur ici ?

result.+

Qu'est-ce que c'est au départ ?

#inject(0)

Peut-on le faire ?

[1, 2, 3, 4].inject(0) { |result, element| result.+ element }

Est-ce que ça marche ?

[1, 2, 3, 4].inject() { |result = 0, element| result.+ element }

Vous voyez, je me base sur l'idée qu'il faut simplement additionner tous les éléments du tableau et obtenir un nombre dans le mémo que vous voyez dans les documents.

Vous pouvez toujours faire ceci

 [1, 2, 3, 4].each { |element| p element }

pour voir l'énumérable du tableau être itéré à travers. C'est l'idée de base.

C'est juste que l'injection ou la réduction vous donne un mémo ou un accumulateur qui est envoyé.

Nous pourrions essayer d'obtenir un résultat

[1, 2, 3, 4].each { |result = 0, element| result + element }

mais rien ne revient, donc tout se passe comme avant.

[1, 2, 3, 4].each { |result = 0, element| p result + element }

dans le bloc de l'inspecteur des éléments.

1voto

Un jour, je me tapais aussi la tête contre les valeurs par défaut des méthodes d'injection/réduction de Ruby, j'ai donc tenté de visualiser mon problème :

default values vizualized

0voto

Il existe une autre forme de la méthode .inject() qui est très utile [4,5].inject(&:+) Cela ajoutera tous les éléments de la zone.

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