В Ruby, как я могу получить сумму нечетных элементов? - PullRequest
2 голосов
/ 31 января 2011

У меня есть массив как:

["4|23", "1", "3|10", "2"]

Я хочу получить сумму нечетных элементов, то есть 1 + 2 = 3, возможно, с inject?

Это ответ Redis ZRANGE WITHSCORES для отсортированного набора. В идеале я хочу получить сумму баллов в отсортированном наборе .

Ответы [ 6 ]

4 голосов
/ 31 января 2011
["4|23", "1", "3|10", "2"].each_slice(2).inject(0) { |i, (j,k)| i += k.to_i }
3 голосов
/ 31 января 2011

Спасибо всем за ваши ответы. Все они были действительно крутыми и поучительными.

Я придумал собственный ответ. Это довольно просто ...

sum = 0; gifts.each_with_index { |s, i| sum += s.to_i if i % 2 == 1 }; sum

Я сделал проверку производительности:

require "benchmark"
MANY = 50000    
gifts = [
  "4|2323", "1",
  "3|102343", "2",
  "0|12330", "1",
  "3|10234873", "2",
  "5|2343225", "1",
  "5|23423744", "1",
  "2|987", "4",
  "0|987345", "1",
  "2|46593", "1",
  "4|78574839", "3",
  "3|4756848578", "1",
  "3|273483", "3"
]

Benchmark.bmbm do |x|
  x.report("each_with_index") { MANY.times { sum = 0; gifts.each_with_index { |s, i| sum += s.to_i if i % 2 == 1 }; sum } }
  x.report("each_with_index") { MANY.times { sum = 0; gifts.each_with_index { |s, i| sum += s.to_i if i.odd? }; sum } }
  x.report("values_at") { MANY.times { gifts.values_at(*(1..gifts.length).step(2)).inject(0) { |s, n| s += n.to_i } } }
  x.report("each_slice") { MANY.times { gifts.each_slice(2).inject(0) { |i, (j,k)| i += k.to_i } } }
  x.report("values_at") { MANY.times { gifts.values_at(*gifts.each_index.select { |i| i.odd? }).map(&:to_i).inject(&:+) } }
  x.report("hash") { MANY.times { Hash[*gifts].values.map(&:to_i).reduce(:+) } }
end

Запустив скрипт выше, выведите на моем Mac следующее:

                      user     system      total        real
each_with_index   0.300000   0.000000   0.300000 (  0.305377)
each_with_index   0.340000   0.000000   0.340000 (  0.334806)
values_at         0.370000   0.000000   0.370000 (  0.371520)
each_slice        0.380000   0.000000   0.380000 (  0.376020)
values_at         0.540000   0.000000   0.540000 (  0.539633)
hash              0.560000   0.000000   0.560000 (  0.560519)

Похоже, мой ответ самый быстрый. Ха-ха. Suckas! : P

3 голосов
/ 31 января 2011
Hash[*a].values.map(&:to_i).reduce(:+)
2 голосов
/ 31 января 2011

Массивы Ruby основаны на 0, поэтому, возможно, вы пытаетесь суммировать значения по нечетным индексам?Если это так, следующее будет выполнять некоторую фильтрацию (i.odd?) и очистку (i.to_i):

>> a = ["4|23", "1", "3|10", "2"]
>> a.values_at(*a.each_index.select{|i| i.odd?}).map{|i| i.to_i}.inject(&:+)
=> 3
1 голос
/ 31 января 2011

Вот, пошагово

# Your array
ary = ["4|23", "1", "3|10", "2"]
# the enumerator to iterate through it
enum = (1..ary.length).step(2)
# your scores
scores = ary.values_at(*enum)
# and the sum
sum = scores.inject(0){ |s,n| s = s + n.to_i }

, что также можно записать как

sum = ary.values_at(*(1..ary.length).step(2)).inject(0){ |s,n| s = s + n.to_i }
0 голосов
/ 29 сентября 2014
array = ["4|23", "1", "3|10", "2"]

array.select.with_index {|e,i|i.odd?}.map(&:to_i).inject(:+)
=> 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...