如何按升序对ruby数组进行排序,但最后保持为零

时间:2011-03-25 06:15:44

标签: ruby-on-rails ruby

我正在尝试使用以下函数对Ruby数组进行排序

@prices = @item.prices.sort { |x,y| x.total <=> y.total }

从最低成本到最高成本的订单。然而,有些产品总共有0.00,我希望它们最后出现而不是出现在顶部。

我尝试了一些方法,但想要一些方法来修改这个块,在底部排序为零,但保持其余的按升序排列。

感谢。

5 个答案:

答案 0 :(得分:3)

尝试这一点,我认为它正在按照您的要求进行:

@prices = @item.prices.sort {|a,b| a.total==0 ? 1 : b.total==0 ? -1 : a.total<=>b.total}

答案 1 :(得分:2)

prices = [0, 1, 2, 0,4, 3]
prices = prices.sort_by do |price|
  [
    if price == 0
      1
    else
      0
    end,
    price
  ]
end
p prices
# => [1, 2, 3, 4, 0, 0]

这里的技巧是通过比较它们的第一个元素来比较数组,但如果这些元素相等,那么通过比较它们的下一个元素,依此类推。因此,让sort_by块生成一个数组可以让您以干净的方式确定主排序顺序,二级排序顺序等。

答案 2 :(得分:2)

仅供记录:

>> a = [0, 1, 3, 0, 2, 5, 0, 9]
=> [0, 1, 3, 0, 2, 5, 0, 9]
>> a.sort_by { |x| x.zero? ? Float::MAX : x }
=> [1, 2, 3, 5, 9, 0, 0, 0]

在大多数平台上1.0/0将评估为Infinity,因此您也可以使用此代替Float::MAX

>> b = [1,4,2,0,5,0]
=> [1, 4, 2, 0, 5, 0]
>> Inf = 1.0/0
=> Infinity
>> b.sort_by { |x| x.zero? ? Inf : x }
=> [1, 2, 4, 5, 0, 0]

答案 3 :(得分:1)

所以设计一个比较器来做到这一点......

if x.total == 0
  # always consider 0 "largest" and no 0 can be larger than another
  # (make sure 0.0 is 0 and not a number really close to 0)
  # perhaps x or y should be first for other reasons as well?
  1
else
  # otherwise lower to higher as normal
  x.total <=> y.total
end

或者没有评论:

foo.sort {|x, y| if x.total == 0 then 1 else x.total <=> y.total end}

快乐的编码。

答案 4 :(得分:0)

对我来说,这会让我觉得不那么苛刻,也不会那么只写:

prices = prices.sort_by do |price| 
  zero_status = price.zero? ? 1 : 0
  [zero_status, price]
end

因为这是按照两个标准对事物进行排序的惯用方法,这就是你在这里做的事情。