我试图理清一个Ruby阵列具有以下功能如何升序排序红宝石阵,但保持零去年
@prices = @item.prices.sort { |x,y| x.total <=> y.total }
从最低到最高成本的订单。然而有些产品总共有0.00,我希望它们最后出现而不是顶部。
我已经尝试了一些东西,但想要一些方法来修改此块在底部排序零,但其余按升序排列。
谢谢。
我试图理清一个Ruby阵列具有以下功能如何升序排序红宝石阵,但保持零去年
@prices = @item.prices.sort { |x,y| x.total <=> y.total }
从最低到最高成本的订单。然而有些产品总共有0.00,我希望它们最后出现而不是顶部。
我已经尝试了一些东西,但想要一些方法来修改此块在底部排序零,但其余按升序排列。
谢谢。
所以,制定一个比较要做到这一点......
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}
快乐编码。
尝试了这一点,我觉得还是做你要求什么:
@prices = @item.prices.sort {|a,b| a.total==0 ? 1 : b.total==0 ? -1 : a.total<=>b.total}
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块生成数组可让您以干净的方式确定主要排序顺序,次要排序顺序等。
只是为了记录:
>> 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]
这会感觉不那么哈克少写 - 只限于我:
prices = prices.sort_by do |price|
zero_status = price.zero? ? 1 : 0
[zero_status, price]
end
beca使用它是一种按照两种标准对事物进行排序的惯用方法,这就是您在这里所做的。
所以,我想你想说 prices.sort_by {| price | [price.zero ?, price]} – 2013-11-20 23:07:40
@aclarke你不能比较'false'和'true',你的代码会导致'ArgumentError:Array与Array的比较失败' – 2013-11-21 02:08:00
我看你是对的 - 这很讨厌!Ruby不是很自由地对这件事感到恼火...... C'est la vie!很高兴我检查了我的消息,我可能会实际上试图在那一天使用。干杯 – 2014-01-20 05:52:20
谢谢,我很接近。 – 2011-03-25 06:43:53
如果你喜欢条件运算符和一个绝望的班轮'foo.sort {| x,y | x.total.zero? ? 1:x.total <=> y.total}' – rubyprince 2011-03-25 08:49:57
这个答案是错误的。问题是它只检查'x.total == 0',但它也应该检查'y.total == 0'并且在这种情况下也返回1。否则,对于某些数组,您不会得到所需的结果,例如:'[2,1,0] .sort {| x,y |如果x == 0,那么1 else x <=> y end}'给出'[0,1,2]'。 (注意,为了简单起见,我跳过了'.total'部分,但问题是一样的。) – antinome 2015-09-15 20:59:40