我怎么能过滤多个条件的对象数组

时间:2015-08-08 04:11:59

标签: ruby

我希望使用相同的flight_datedeparture_at,'arrival_at','from','to','price'过滤商品。

否则,我会保留持续的(updated_at字段)。

我怎么能用ruby

来做这件事

原始数组

[
{
  "_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 个答案:

答案 0 :(得分: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}] 

<强>替代

每当使用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的形式,它使用一个块来确定合并的两个哈希中存在的键的值(两个哈希值是块变量的值{{1 }和o)。