2017-05-20 2 views
0

Ich habe ein Array mit Arrays, die einen Schlüssel und einen Zeitstempel enthalten.Ruby on Rails Array-Gruppe nach Wert sortieren

["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 22:00:51 CEST +02:00], 
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 22:00:32 CEST +02:00], 
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:58:33 CEST +02:00], 
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:58:01 CEST +02:00], 
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:58:51 CEST +02:00], 
["3wyadsrrdxtgieyxx_lgka", Sat, 13 May 2017 01:09:01 CEST +02:00], 
["y-5he42vlloggjb_whm8jw", Sat, 22 Apr 2017 22:48:31 CEST +02:00], 
["oaxej30u9we17onlug4orw", Sun, 23 Apr 2017 01:46:48 CEST +02:00], 
["oaxej30u9we17onlug4orw", Sun, 23 Apr 2017 02:06:56 CEST +02:00], 
["rqjwg1ka43mvri0dmrdxvg", Sun, 23 Apr 2017 17:23:34 CEST +02:00], 
["ok8nq6tg-kor9jglsuhoyw", Tue, 25 Apr 2017 13:02:16 CEST +02:00], 
["riwfm0m-0rmbb6e9kyug2g", Sat, 06 May 2017 06:12:27 CEST +02:00], 
["riwfm0m-0rmbb6e9kyug2g", Sat, 06 May 2017 06:17:01 CEST +02:00], 
["riwfm0m-0rmbb6e9kyug2g", Sat, 06 May 2017 06:18:04 CEST +02:00], 
["gbqfn3_d_tritqoey5khjw", Sat, 06 May 2017 14:14:55 CEST +02:00], 
["j___x1oap-veh0u1fo_oua", Sun, 07 May 2017 14:22:37 CEST +02:00], 
... 

Ich habe diese Liste von ActiveRecord erhalten.

MyModel.all.pluck(:token, :created_at) 

Das Modell enthält einige uniq-Tokens und einige Duplikate. Die Duplikate sind interessant.

Ich möchte die Zeitstapel mit dem Schlüssel gruppieren und nach dem ersten und dem letzten Zeitstempel für jeden Schlüssel suchen. So gruppiert ich das Array wie folgt:

grp = arr.group_by { |key, ts| key} 

Jetzt erhalte ich eine Liste wie folgt aus:

"vwfv8n5obwqmaw8r9fj-yq"=>[ 
["vwfv8n5obwqmaw8r9fj-yq", Thu, 11 May 2017 10:24:42 CEST +02:00] 
], 
"kacec6ybetpjdzlfgnnxya"=> [ 
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 22:00:31 CEST +02:00], 
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 22:01:43 CEST +02:00], 
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:58:17 CEST +02:00], 
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:59:05 CEST +02:00], 
["kacec6ybetpjdzlfgnnxya", Fri, 12 May 2017 21:59:59 CEST +02:00] 
], 
... 

Ist es möglich, die Daten zu sortieren, das erste und das letzte Datum leicht zu bekommen? Bin ich zu kompliziert? Ich denke, es sollte einen einfacheren Weg geben, mit den Rohdaten umzugehen.

+0

Sind die Daten von einem beliebigen DB kommt? Meinst du, du hast ein Array von Arrays? – max

+0

Ja, mit .pluck (: token,: created_at) –

+0

Können Sie uns einen Auszug aus 'config/schema.rb' und dem Modell geben? Es ist viel einfacher (und effektiver), stattdessen die Datenbankabfrage zu sortieren und zu gruppieren. – max

Antwort

1

aa Hash mit dem Token zu erhalten als Schlüssel und Zeitstempel als Werte:

# this gives the same MIN and MAX if there is only one created_at in the group 
rows = MyModel.group(:token) 
    .pluck("token, MIN(created_at), MAX(created_at)") 

# loop though rows and create a hash 
rows.each_with_object({}) do |(token, *t), hash| 
    hash[token] = t.uniq # removes dupes 
end 

{ 
"rqjwg1ka43mvri0dmrdxvg"=>[2017-04-23 15:23:34 UTC], 
"riwfm0m-0rmbb6e9kyug2g"=>[2017-05-06 04:12:27 UTC, 2017-05-06 04:18:04 UTC] 
    # ... 
} 

Wenn Sie einfach nur für die Datensätze suchen, die Duplikate müssen Sie nur verwenden können eine WHERE-Klausel, die die Datensätze zählt:

MyModel.where("(SELECT COUNT(*) FROM things t WHERE t.token = things.token) > 1") 
+0

MIN (created_at), MAX (created_at) ist absolut erstaunlich. Wusste das nicht. Das hilft viel. –

0

versuchen, etwas wie folgt aus:

MyModel.order(:created_at).pluck(:token, :created_at).group_by { |key, ts| key }.flat_map{ |k, v| { k => [v.first, v.last] } } 
0

Sie können dies tun:

# you already have this bit 
grp = arr.group_by { |key, ts| key} 

# get the minmax values for each group 
grp.map { |k, values_array| { k => values_array.minmax } }.reduce Hash.new, :merge 

Dies sollte etwas ergeben, das wie folgt aussieht:

{ 
    "vwfv8n5obwqmaw8r9fj-yq"=>[ 
    [Thu, 11 May 2017 10:24:42 CEST +02:00, Thu, 11 May 2017 10:24:42 CEST +02:00] 
    ], 
    "kacec6ybetpjdzlfgnnxya"=> [ 
    [Fri, 12 May 2017 21:58:17 CEST +02:00, Fri, 12 May 2017 22:01:43 CEST +02:00] 
    ], 
    ... 
} 
+0

es ergibt sich nicht so .. –