2017-05-20 6 views
0

私はキーとタイムスタンプを含む配列を持つ配列を持っています。Ruby on Railsアレイグループの値で並べ替え

["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], 
... 

このリストはActiveRecordから届きました。

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

ユニークなトークンといくつかの重複を含むモデルです。 重複は面白いです。

タイムストップをキーでグループ化し、各キーの最初と最後のタイムスタンプを探したいとします。 は、だから私は、次のように配列をグループ化:

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

今、私はこのようなリストを受け取る:

"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] 
], 
... 

は、それは簡単に最初と最後の日付を取得するには日付を並べ替えることは可能ですか? 私は複雑すぎるのですか?生データを扱う簡単な方法があるはずです。

+0

はDBからのデータですか?配列の配列を持っているということですか? – max

+0

はい、.pluck(:token、:created_at) –

+0

'config/schema.rb'とモデルの抜粋を教えてください。その代わりに、データベース照会でソートしてグループ化する方がはるかに簡単です(さらに効果的です)。 – max

答えて

1

をキーとタイムスタンプを値として使用:

# 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] 
    # ... 
} 

あなたは、単にあなただけのレコードをカウントしWHERE句を使用することができ、重複していたレコードを探している場合:

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

MIN(created_at)、MAX(created_at)は絶対に素晴らしいです。それを知らなかった。それはたくさんの助けになります。 –

0

はこのような何かを試してみてください。

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

あなたがこれを行うことができます:

# 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 

これがどのように見える何かを得なければならない:トークンでAAハッシュを取得するには

{ 
    "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

それはそのようには得られません.. –

関連する問題