2016-11-22 3 views
2

Как создать новый массив для суммирования элементов массива в Ruby?Как я могу суммировать элементы массива в рубине?

[1,2,3,4,5].each_cons(2).map {|a, b| a + b } 

дает мне [3, 5, 7, 9], но ожидаемый результат [1,3,6,10,15].

+0

⇑ Добро пожаловать, PHP! – mudasobwa

+0

Да, только старое решение школы .. :) –

+0

@MuratUstuntas что означает «на месте»? – Stefan

ответ

1
[1, 2, 3, 4, 5].each_with_object([]){|e, a| a.push(a.last.to_i + e)} 
# => [1, 3, 6, 10, 15] 
+0

Большое вам спасибо :) realy самые быстрые ответы .. –

+0

'to_i' приводит к сбою, скажем, строк. – mudasobwa

+3

'# to_i', безусловно, существует для соглашения, что' nil.to_i' возвращает '0'. Направлено только номерами. –

0

Это не очень элегантно, но это, кажется, работает:

[1,2,3,4,5].each_with_object([]){|i,l| l<<(l.last||0)+i} 
#=> [1,3,6,10,15] 
+0

@MuratUstuntas это безумие (кроме того, что это не победитель, пересмотреть свои тесты). Разница в половине наносекунды не должна иметь значения при выборе правильного решения. – mudasobwa

+0

Я согласен с @mudasobwa: ваш тест в основном показывает, что нет больших статистических различий между этими реализациями. Поэтому выбирайте только в зависимости от, скажем, читаемости кода и ознакомления с используемыми методами. –

+0

Да, вы правы. Я просто говорю слово. Если я ошибся, простите меня. :) –

2

много способов сделать это. Один из способов заключается в создании Enumerator экземпляра и использовать inject:

def adder array 
    enum = Enumerator.new do |y| 
    array.inject (0) do |sum, n| 
     y << sum + n 
     sum + n 
    end 
    end 
    enum.take array.size 
end 

adder [1,2,3,4,5] #=> [1, 3, 6, 10, 15] 
+1

'(sum + n) .tap & y.method (: <<)' – mudasobwa

+0

@mudasobwa, да, это отличная идея. –

1

Другой вариант:

> [1, 2, 3, 4, 5].reduce([]) {|acc, el| acc << el + (acc[-1] || 0); acc} 
#=> [1, 3, 6, 10, 15] 

Yuk.

+1

Если вы используете add/reduce и должны возвращать объект во втором выражении внутри блока, это означает, что вы, вероятно, можете использовать each_with_object. –

8

Более простой для понимания, я думаю:

temp_sum = 0 
arr.map! {|e| temp_sum += e } 
=> [1, 3, 6, 10, 15] 

Если вы хотите создать новый массив вместо существующего, просто использовать map вместо map!

+1

Первый ответ на этот вопрос, отвечая на вопрос «на месте». У этого есть недостаток в производстве N сумм, но он может быть исправлен с помощью '.with_object (tempor_sum)'. – mudasobwa

+0

@mudasobwa, исправлено :) – Ilya

+1

Отличный ответ. .... – sawa

Смежные вопросы