2017-01-07 4 views
1

Ich habe diese Anfrage:Rails 5: Gruppe Datetime in Hash Jahr, Monat, Tag

dates = MyModel.pluck("distinct date(datetime_column)") 
Hash[dates.group_by(&:year).map{|y, items| [y, items.group_by{|d| d.month}]}] 

, die unterschiedlichen Termine zu finden und gibt mir dann diesen Array:

=> {2017=>{12=>[Tue, 12 Dec 2017], 1=>[Sun, 01 Jan 2017]}, 
2016=>{11=>[Sun, 20 Nov 2016], 12=>[Sat, 24 Dec 2016, Mon, 12 Dec 2016, Fri, 30 Dec 2016]}} 

Wie kann ich 3. Ebene hinzufügen, um Hash zu haben, wo es bestimmte Tage unter jedem Monat gibt? Danke für jede Hilfe!

aktualisieren

Wenn jemand bestellt Ergebnis braucht, versuchen Sie dies für "dates" Teil:

dates = MyModel.order(:datetime_column).distinct.pluck(:datetime_column)

Für eine bessere Leistung, dies zu nutzen versuchen:

dates = MyModel.order("date_trunc('day', datetime_column) DESC") 
       .distinct.pluck("date_trunc('day', datetime_column)") 

Hier ist schön blog post on using datetrunc.

Antwort

1

Sie each_with_object verwenden können, aber Sie müssen richtig um das Objekt zu initialisieren. Es ist ein Hash of Hashes of Hashes!

require 'date' 
a = Date.today 
b = Date.new(2017,1,3) 
c = Date.new(2015,12,5) 
d = Date.new(2015,11,7) 

dates = [a,b,c,d] 

hash = Hash.new { |h, y| h[y] = Hash.new { |h2, m| h2[m] = {} } } 

dates_by_ymd = dates.each_with_object(hash) do |date, h| 
    h[date.year][date.month][date.day] = date 
end 

require 'pp' 
pp dates_by_ymd 

# {2017=> 
# {1=> 
#  {7=>#<Date: 2017-01-07 ((2457761j,0s,0n),+0s,2299161j)>, 
#  3=>#<Date: 2017-01-03 ((2457757j,0s,0n),+0s,2299161j)>}}, 
# 2015=> 
# {12=>{5=>#<Date: 2015-12-05 ((2457362j,0s,0n),+0s,2299161j)>}, 
# 11=>{7=>#<Date: 2015-11-07 ((2457334j,0s,0n),+0s,2299161j)>}}} 

In Ihrem Fall würden Sie schreiben:

dates = MyModel.pluck("distinct date(datetime_column)") 
hash = Hash.new { |h, y| h[y] = Hash.new { |h2, m| h2[m] = {} } } 

dates_by_ymd = dates.each_with_object(hash) do |date, h| 
    h[date.year][date.month][date.day] = date 
end 

Beachten Sie, dass dieser Code Date Objekte wie Blätter des verschachtelten Hash zurückgibt, wie Sie in Ihrer Frage erwähnt.

Wenn Sie eine modifizierte Version des Codes möchten, können Sie diesen Rails-Code verwenden:

dates.group_by(&:year).map do |y, items| 
    [y, items.group_by(&:month).map { |m, days| [m, days.index_by(&:day)] }.to_h] 
end.to_h 
+0

'verschiedene Datum (datetime_column)' - es gibt ein Date-Objekte sind (nicht Zeit) – Ilya

+0

@Ilya Also? Beide Objekte antworten auf "Jahr", "Monat" und "Tag". Auf diese Weise kann ich überprüfen, ob mein Code funktioniert, und übrigens, dass Ihr Code nicht funktioniert. –

+0

Danke! Was sagst du über @Inpego vorgeschlagene Lösung? – matiss

1

Versuchen

dates = MyModel.pluck("distinct date(datetime_column)") 
dates.group_by(&:year).map do |y, items| 
    [y, items.group_by(&:month).map { |m, days| [m, days.map(&:day)] }.to_h] 
end.to_h 
+0

Danke, das funktioniert wie Charme :) – matiss

Verwandte Themen