2017-08-21 7 views
-2

タイミングとデータを含むjsonオブジェクトの配列があります。基本的にはjson配列からclose time要素を削除する

、各要素は、私の目標は、ユーザーIDが同じであればお互いに近すぎるオブジェクトを削除することです

[ 
    { 
    "id": "abc", 
    "ts": "2017-08-17T20:42:12.557229", 
    "userid": "seb" 
    }, 
    { 
    "id": "def", 
    "ts": "2017-08-17T20:42:52.724773", 
    "userid": "seb" 
    }, 
    { 
    "id": "ghi", 
    "ts": "2017-08-17T20:42:53.724773", 
    "userid": "matt" 
    }, 
    { 
    "id": "jkl", 
    "ts": "2017-08-17T20:44:50.557229", 
    "userid": "seb" 
    }, 
    { 
    "id": "mno", 
    "ts": "2017-08-17T20:44:51.724773", 
    "userid": "seb" 
    }, 
    { 
     "id": "pqr", 
     "ts": "2017-08-17T20:50:52.724773", 
     "userid": "seb" 
    } 
] 
以下のようにタイミング、IDとユーザーが含まれています。時間差が2秒未満の場合、要素を削除します。それは同じではないよう

リストから

、私はリストのユーザマットとSEBのための2つのオブジェクトが2秒以下でお互いに近すぎる場合でも

[ 
    { 
    "id": "abc", 
    "ts": "2017-08-17T20:42:12.557229", 
    "userid": "seb" 
    }, 
    { 
    "id": "def", 
    "ts": "2017-08-17T20:42:52.724773", 
    "userid": "seb" 
    }, 
    { 
    "id": "ghi", 
    "ts": "2017-08-17T20:42:53.724773", 
    "userid": "matt" 
    }, 
    { 
     "id": "pqr", 
     "ts": "2017-08-17T20:50:52.724773", 
     "userid": "seb" 
    } 
] 

を取得する必要があり、我々は要素を維持する必要がありますユーザー

"ts": "2017-08-17T20:42:52.724773" for seb 

"ts": "2017-08-17T20:42:53.724773" for matt 

Rubyでそれをコーディングする方法任意のアイデア?私はいつも要素nをn-1と比較し、必要に応じてn-1を削除する

+0

これまでに何を試してみましたか、それに何が問題ですか?開始する場所が必要な場合は、[Hash](https://ruby-doc.org/core-2.4.0/Array.html)の[Array](https://ruby-doc.org/) core-2.4.0/Hash.html)オブジェクトを使用し、[Time](https://ruby-doc.org/core-2.4.0/Time.html)の違いをチェックする必要があります。それらのクラス、および親クラスまたは含まれているモジュールのために、役立つと思われるものがあるかどうかを確認してください。 –

+0

配列が '{{id:" abc "、 ts:2017-08-17T20:40:00.0、userid:" seb "}、{id:" def "、ts:2017の場合の戻り値は何ですか? -08-17T20:40:01.1、userid: "seb"}、{id: "ghi"、ts:2017-08-17T20:40.02.2、userid: "seb"}] '?私はキーがシンボルであると仮定しているので、引用符は不要で、時刻は 'Time'や' DateTime'オブジェクトなので引用符はそこには適用されません。 –

+0

_both_、id '' jkl''とid '' mno''を削除したいのは間違いですか? – Stefan

答えて

0
require 'time' 

result = [] 

timestamps = {} 

data.each do |item| 
    ts = timestamps[item['userid']] 

    if ts.nil? or Time.parse(item['ts']) - Time.parse(ts) > 2 
    result.push(item) 
    timestamps[item['userid']] = item['ts'] 
    end 
end 

puts result 
0

以下のコードはどうですか?

レコードの順序が変更されますが、必要に応じて並べ替えることができます。

require 'date' 

def time_elapsed_in_seconds(start_time, end_time) 
    ((end_time - start_time) * 24 * 60 * 60).to_i 
end 

def too_close?(first_time, second_time, threshold = 2) 
    time_elapsed_in_seconds(first_time, second_time) < threshold 
end 

def datetimes(a, b) 
    return [DateTime.parse(a), DateTime.parse(b)] 
end 

def should_reject_record?(record, next_record) 
    datetimes = datetimes(record[:ts], next_record[:ts]) 
    record[:userid] == next_record[:userid] && too_close?(*datetimes) 
end 

def filter_records(records) 
    sorted = records.sort_by{|record| [record[:userid], record[:ts]] } 
    sorted.select.with_index do |record, index| 
    previous_record = sorted[index-1] 
    record == sorted.first || !should_reject_record?(previous_record, record) 
    end 
end 

records = [ 
    { 
    "id": "abc", 
    "ts": "2017-08-17T20:42:12.557229", 
    "userid": "seb" 
    }, 
    { 
    "id": "def", 
    "ts": "2017-08-17T20:42:52.724773", 
    "userid": "seb" 
    }, 
    { 
    "id": "ghi", 
    "ts": "2017-08-17T20:42:53.724773", 
    "userid": "matt" 
    }, 
    { 
    "id": "jkl", 
    "ts": "2017-08-17T20:44:50.557229", 
    "userid": "seb" 
    }, 
    { 
    "id": "mno", 
    "ts": "2017-08-17T20:44:51.724773", 
    "userid": "seb" 
    }, 
    { 
     "id": "pqr", 
     "ts": "2017-08-17T20:50:52.724773", 
     "userid": "seb" 
    } 
] 

puts filter_records(records) 
関連する問題