Ruby: суммирование значений в массиве хэшей между определенными датами - PullRequest
3 голосов
/ 05 мая 2011

У меня есть массив хэшей в Ruby:

array = [
  {:date => Wed, 04 May 2011 00:00:00 PDT -07:00,
   :value => 200}
  {:date => Wed, 04 May 2011 01:00:00 PDT -07:00,
   :value => 100}
  {:date => Tue, 03 May 2011 01:00:00 PDT -07:00,
   :value => 300}
  {:date => Tue, 03 May 2011 01:00:00 PDT -07:00,
   :value => 150}
]

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

array = [
  {:date => Wed, 04 May 2011 00:00:00 PDT -07:00,
   :value => 300}
  {:date => Tue, 03 May 2011 00:00:00 PDT -07:00,
   :value => 450}
]

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

Это то, что я изначально пробовал:

entries = [
  {:date => Wed, 04 May 2011 00:00:00 PDT -07:00,
   :value => 200}
  {:date => Wed, 04 May 2011 01:00:00 PDT -07:00,
   :value => 100}
  {:date => Tue, 03 May 2011 01:00:00 PDT -07:00,
   :value => 300}
  {:date => Tue, 03 May 2011 01:00:00 PDT -07:00,
   :value => 150}
]

first_day = 29.days.ago.beginning_of_day
total_days = 30

day_totals = (0...total_days).inject([]) do |array, num|
    startat = first_day + num.day
    endat = startat.end_of_day

    total_value_in_day = entries.where("date >= ? and date <= ?", startat, endat).sum(:value)

    array << {:date => startat, :value => total_value_in_day}
end

Я осознал свою ошибкубыл с where методом, который является методом Rails для поиска объектов и не может использоваться на массивах.Поэтому мой главный вопрос, есть ли способ поиска в массивах или хэшах с условиями.

Ответы [ 2 ]

5 голосов
/ 05 мая 2011

Вы можете перебирать записи для создания нового массива:

totals = Hash.new(0)
array.each do |entry|
  totals[entry[:date]] += entry[:value]
end

# Now totals will be something like this:
# => {"Wed, 04 May 2011" => 300, "Tue, 03 May 2011" => 450...}

# If you then want this in the same array format you started with:
new_array = totals.collect{ |key, value| {:date => key, :value => value} }
# => [{:date => "Wed, 04 May 2011", :value => 300}, {....}]
3 голосов
/ 05 мая 2011

Для 1.9.2:

>> array.each_with_object(Hash.new(0)) { |el, hash| hash[el[:date]] += el[:value] } 
#=> {"Wed, 04 May 2011 00:00:00 PDT -07:00"=>200, "Wed, 04 May 2011 01:00:00 PDT -07:00"=>100, "Tue, 03 May 2011 01:00:00 PDT -07:00"=>450}

Также работает с 1.8:

>> array.inject(Hash.new(0)) { |hash, el| hash[el[:date]] += el[:value] ; hash } 
#=> {"Wed, 04 May 2011 00:00:00 PDT -07:00"=>200, "Wed, 04 May 2011 01:00:00 PDT -07:00"=>100, "Tue, 03 May 2011 01:00:00 PDT -07:00"=>450}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...