复杂的排序和数据收集

时间:2016-08-05 17:13:47

标签: ruby-on-rails arrays sorting hash

我有一个订单详细信息的哈希,详细信息在一个数组中。从那我想收集一个唯一的用户名列表。为此,我想基于订单日期时间对数组进行排序(即最后一个订单成为第一个),如果订单日期时间不可用,则根据订单ID对其进行排序。因此,列表中的名称将是具有订单日期时间的名称,并将名称没有订单日期时间放在列表的末尾。以下是我的哈希:

{
    "orderDetails": [
        {
            "orderId": 11,
            "orderDtTm": "2016-08-04T19:39:06.000Z",
            "orderTz": "America/Chicago",
            "user": {
                "userId": 1,
                "userName": "Joe, SMITH"
            }
        },
        {
            "orderId": 10,
            "user": {
                "userId": 2,
                "userName": "Lynn, WILSON"
            }
        },
        {
            "orderId": 25,
            "orderDtTm": "2016-08-04T20:39:06.000Z",
            "orderTz": "America/Chicago",
            "user": {
                "userId": 1,
                "userName": "Joe, SMITH"
            }
        },
        {
            "orderId": 33,
            "user": {
                "userId": 3,
                "userName": "Mark, Taylor"
            }
        },
        {
            "orderId": 16,
            "orderDtTm": "2016-08-04T21:53:09.000Z",
            "orderTz": "America/Chicago",
            "user": {
                "userId": 3,
                "userName": "Mark, Taylor"
            }
        }
    ]
}

由于订单1,3和5具有订单日期时间,我的初始列表将根据最后下订单排序,订单为5,3和1,即["Mark, Taylor", "Joe, SMITH", "Joe, SMITH"],并根据订单添加其他名称id因为他们没有订单日期时间,那就是订单4然后是2.所以我最后的数组是["Mark, Taylor", "Joe, SMITH", "Joe, SMITH", "Mark, Taylor", "Lynn, WILSON"]

因为我想要我会做的唯一用户名:

["Mark, Taylor", "Joe, SMITH", "Joe, SMITH", "Mark, Taylor", "Lynn, WILSON"].uniq就可以获得["Mark, Taylor", "Joe, SMITH", "Lynn, WILSON"]

我的代码:

order_details = order_details_data[:orderDetails]

order_details_array = order_details.sort_by { |key| key[:orderDtTm]|| key[:orderId] }.reverse
user_names_set = Set.new

order_details_array.each do |obj|
    user_name = obj[:user][:userName]
    user_names_set << user_name unless user_name.blank?
end

如果我总是有订单日期时间,这可以正常工作,但是当我没有订单日期时间时会给出意想不到的输出。

1 个答案:

答案 0 :(得分:0)

尝试使用自定义比较器而不是sort_by。像

这样的东西
order_details_array = order_details.sort do |a,b| 
  if a[:orderDtTm] && b[:orderDtTm]
    b[:orderDtTm] <=> a[:orderDtTm]
  elsif a[:orderDtTm] && !b[:orderDtTm]
    -1
  elsif !a[:orderDtTm] && b[:orderDtTm]
    1
  else
    b[:orderId] <=> a[:orderId]
  end  
end

而不是

order_details_array = order_details.sort_by { |key| key[:orderDtTm]|| key[:orderId] }.reverse