Как inject обрабатывает первый элемент массива при суммировании?

У меня есть:

arr=[40, 50, 60, 70]

arr.inject do |sum,x|
  p x
  p sum
  if x>50
    sum=sum+x
  end
  p sum
end

Почему x начинается с 50, а sum начинается с 40? Я предполагаю, что x сначала будет повторять более 40. Еще лучше, как сделать, чтобы этот оператор, используя метод inject, возвращал 130?


person notthehoff    schedule 05.01.2014    source источник


Ответы (2)


Inject использует первый элемент массива в качестве начальной суммы и выполняет блок, начиная со второго элемента. Вы можете передать начальную сумму для ввода с помощью inject(0) do ..end. Затем он начнется с sum, равного 0, и выполнит блок с первого элемента. Также обратите внимание, что sum присваивается значению исполняемого блока, поэтому ваш код вообще не будет работать. Так должно быть:

arr=[40, 50, 60, 70]

arr.inject do |sum,x|
  x > 50 ? sum+x : sum
end

Однако я бы написал немного проще:

arr=[40, 50, 60, 70]

arr.select {|v| v > 50}.reduce(0, &:+)

Если вы используете Active Support (от Rails), вы можете просто сделать:

arr.select {|v| v > 50}.sum
person BroiSatse    schedule 05.01.2014
comment
Спасибо за советы. У меня он был не такой короткий, как у вас, но я записал его во время эксперимента. Благодарю вас! - person notthehoff; 05.01.2014

Если вы не предоставите аргумент методу inject, значение sum будет значением первого элемента в массиве. Если вы хотите, чтобы это было 100, начните свой код с arr.inject(100).

person daremkd    schedule 05.01.2014