2015-08-08 3 views
-2

Я хочу фильтровать элементы с одинаковыми flight_date, departure_at, 'arrival_at', 'from', 'to', 'price'.Как фильтровать массив объектов с несколькими условиями

В противном случае, я сохраню длительный (на поле updated_at).

Как я мог бы сделать это с рубином

исходного массива

[ 
{ 
    "_id": ObjectId("55c553af506f6325ef000005"), 
    "flight_date": new Date("2015-08-13T08:00:00+0800"), 
    "departure_at": new Date("2015-08-13T19:35:00+0800"), 
    "arrival_at": new Date("2015-08-13T23:15:00+0800"), 
    "from": "KHH", 
    "to": "KIX", 
    "updated_at": new Date(1438995375908), 
    "price": 3898 
}, 
... 
{ 
    "_id": ObjectId("55c553af506f6325ef000009"), 
    "flight_date": new Date("2015-08-13T08:00:00+0800"), 
    "departure_at": new Date("2015-08-13T19:35:00+0800"), 
    "arrival_at": new Date("2015-08-13T23:15:00+0800"), 
    "from": "KHH", 
    "to": "KIX", 
    "updated_at": new Date(1438995375999), 
    "price": 3898 
} 
] 

Ожидаемый выходной массив

[ 
    { 
     "_id": ObjectId("55c553af506f6325ef000005"), 
     "flight_date": new Date("2015-08-13T08:00:00+0800"), 
     "departure_at": new Date("2015-08-13T19:35:00+0800"), 
     "arrival_at": new Date("2015-08-13T23:15:00+0800"), 
     "from": "KHH", 
     "to": "KIX", 
     "updated_at": new Date(1438995375999), 
     "price": 3898 
    } 
] 
+1

Это даже не рубиновый массив - никогда не видел код типа 'new Date (...)' в Ruby. Ваш код не компилируется в Ruby. –

ответ

2

Мои понять, что, учитывая массив хэшей, вы хотите сгруппировать в хешей h на величину массива:

[h[:flight_date], h[:departure_at], h[:arrival_at], 
    h[:from], h[:to], h[:price]] 

и в каждой группе вы хотите сохранить ту, для которой h[:updated_at] является самой большой. Если это верно, то это один из способов сделать это, используя Enumerable#group_by:

def filter_flights(arr) 
    arr.group_by { |h| [h[:flight_date], h[:departure_at], h[:arrival_at], 
    h[:from], h[:to], h[:price]] }. 
    values. 
    map { |a| a.max_by { |h| h[:updated_at] } } 
end 

Ваш массив хэшей не может быть использован, как есть, так что я упростил ее.

arr = [ 
{ 
    "_id": "55c553af506f6325ef000005", 
    "flight_date": "2015-08-13T08:00:00+0800", 
    "departure_at": "2015-08-13T19:35:00+0800", 
    "arrival_at": "2015-08-13T23:15:00+0800", 
    "from": "KHH", 
    "to": "KIX", 
    "updated_at": 1438995375908, 
    "price": 3898 
}, 
{ 
    "_id": "55c553af506f6325ef000009", 
    "flight_date": "2015-08-13T08:00:00+0800", 
    "departure_at": "2015-08-13T19:35:00+0800", 
    "arrival_at": "2015-08-13T23:15:00+0800", 
    "from": "KHH", 
    "to": "KIX", 
    "updated_at": 1438995375999, 
    "price": 3898 
} 
] 

filter_flights(arr) 
    #=> [{:_id=>"55c553af506f6325ef000005", 
    #  :flight_date=>"2015-08-13T08:00:00+0800", 
    #  :departure_at=>"2015-08-13T19:35:00+0800", 
    #  :arrival_at=>"2015-08-13T23:15:00+0800", 
    #  :from=>"KHH", 
    #  :to=>"KIX", 
    #  :updated_at=>1438995375999, 
    #  :price=>3898}] 

Alternative

Всякий раз, когда проблема может быть решена с помощью Enumerable#group_by, вы можете быть уверены, что есть другой способ (это правило одинаково хорошо) с помощью Hash#update (ака merge!). Вот оно:

def filter_flights(arr) 
    arr.each_with_object({}) do |g,h| 
    a = [g[:flight_date], g[:departure_at], g[:arrival_at], 
     g[:from], g[:to], g[:price]] 
    h.update(a=>g) { |_,o,n| (o[:updated_at] >= n[:updated_at]) ? o : n } 
end.values 

Здесь я использовал форму Hash#update, которая использует блок для определения значений ключей, которые присутствуют в обеих хешах быть объединен (два хэш быть значением блока переменных o и n).

Смежные вопросы