Ruby: объединение массивов или хэшей - PullRequest
4 голосов
/ 05 апреля 2011

Мне трудно понять, как решить эту проблему, по сути, у меня есть два массива, которые выглядят так:

Первый массив:

days_to_report
#=> [{:date=>Fri, 01 Apr 2011},
#=>  {:date=>Sat, 02 Apr 2011},
#=>  {:date=>Sun, 03 Apr 2011},
#=>  {:date=>Mon, 04 Apr 2011}]

Второй массив:

tracks_by_day
#=> [{:date=>Mon, 04 Apr 2011, :count=>905, :percentage=>13.205895228367137},
#=>  {:date=>Sat, 02 Apr 2011, :count=>6745, :percentage=>98.4240478622501},
#=>  {:date=>Fri, 01 Apr 2011, :count=>6853, :percentage=>100.0}]

Даты, являющиеся Date объектами в данном случае.

Поэтому я хочу объединить их так, чтобы для каждого элемента в первом массиве (days_to_report) имелосьданные, которые есть во втором массиве, например, идеальный результат: (обратите внимание на данные для даты для Sun, 3 апреля 2011 г.)

[{:date=>Mon, 04 Apr 2011, :count=>905,  :percentage=>13.205895228367137},
 {:date=>Sun, 03 Apr 2011, :count=>0,    :percentage=>0},
 {:date=>Sat, 02 Apr 2011, :count=>6745, :percentage=>98.4240478622501},
 {:date=>Fri, 01 Apr 2011, :count=>6853, :percentage=>100.0}]

Обратите внимание, что второй элемент массива имеет ноль длязначения, потому что :date не было в хэше для массива tracks_by_day ... есть мысли о том, как этого добиться?Похоже на функциональность, предоставленную в zip, или что-то в этом роде, но мне нужно сопоставить ключи, чтобы увидеть, существуют ли они, и заполнить их значения нулями, если их нет.правильно, еще раз спасибо, ребята!Дай пять!

Ответы [ 4 ]

2 голосов
/ 05 апреля 2011
days = days_to_report.map{|d| d[:date] } - tracks_by_day.map{|d| d[:date]}
days.each{ |d| tracks_by_day << {:date => d, :count => 0, :percentage => 0} }

OR

days.inject(tracks_by_day){|a,d| a << {:date => d, :count => 0, :percentage => 0}}
1 голос
/ 05 апреля 2011

Попробуйте это:

idx = tracks_by_day.index_by {|r| r.first }
days_to_report.map do |r| 
  data = (idx[r.first] || []).first || {:count=>0,    :percentage=>0}
  r.merge(data)
end
1 голос
/ 05 апреля 2011

Вот как я это сделаю, пока не будет большого количества элементов:

days_to_report.each do |day_hash|
  tracks = tracks_by_day.find {|h| h[:date] == day_hash[:date]}
  day_hash.merge!(tracks || {:count=>0, :percentage=>0})
end

Если tracks_by_day огромен, вы можете сначала преобразовать его в хеш, который отображает датык их данным.

0 голосов
/ 05 апреля 2011
(days_to_report+tracks_by_day).group_by {|h| h[:date]}.
   map{|date, (h1, h2)| {:count => 0, :percentage => 0}.merge(h1).merge(h2 || {})}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...