【发布时间】:2014-07-11 01:39:06
【问题描述】:
我最近遇到了一段代码
array.sort{|x,y| y <=> x}
按降序对整数数组进行排序。我查看了 运算符并了解到它返回三个不同的值,-1、0 或 1,具体取决于一个值是否小于、大于或等于另一个值。
但我无法解释为什么上面的代码会按降序对数组进行排序,但我知道这肯定要归功于 IRB。这里发生了什么?谁能给我解释一下?
【问题讨论】:
我最近遇到了一段代码
array.sort{|x,y| y <=> x}
按降序对整数数组进行排序。我查看了 运算符并了解到它返回三个不同的值,-1、0 或 1,具体取决于一个值是否小于、大于或等于另一个值。
但我无法解释为什么上面的代码会按降序对数组进行排序,但我知道这肯定要归功于 IRB。这里发生了什么?谁能给我解释一下?
【问题讨论】:
出于同样的原因:
array.sort{|x,y| x <=> y}
按升序排列。
以这个程序为例:
[1,5,2,4,3].sort do |x,y|
puts "---"
puts x
puts y
puts x <=> y
x <=> y
end
它将输出它正在比较的两个数字,然后在排序过程中输出<=> 的结果。它输出这个:
---
1
2
-1 # 1 is less than 2
---
2
3
-1 # 2 is less than 3
---
5
2
1 # 5 is greater than 1
---
4
2
1 # 4 is greater than 2
---
5
4
1 # 5 is greater than 4
---
4
3
1 # 4 is greater than 3
如果您将x <=> y 的顺序颠倒为y <=> x,您将得到相反的结果。
【讨论】:
因为你做了 y x,而不是 x y。论据的顺序很重要。
【讨论】:
我选择了一个我希望大多数 Ruby 新手都能理解的答案。
Array#sort 比较数组中的每一对元素。对于每对元素x,y,sort 的块返回-1 如果x 在排序中在y 之前,1 如果y 在x 和0 之前另一个。如果没有给出块,sort 使用块:
{ |x,y| x <=> y }
例如,如果 x 和 y 是字符串,则方法 String#<=> 可能会这样定义:
class String
def <=>(other)
case
when self < other then -1
when self > other then 1
else 0
end
end
end
同样,如果x 和y 是数组,则调用Array#<=>,依此类推。对于Fixnums、Bignums 和Floats(所有这些都来自Numeric 的后代类),使用了Numeric#<=> 方法,因此被排序的数组可以包含这些的混合三种数据类型。
如果sort的块是:
{ |x,y| y <=> x }
块返回此处显示的值(与默认x <=> y 的值进行比较):
现在假设我们希望对数组[2,3,1,2] 进行排序。对于默认的sort,带有x <=> y 的排序块返回此处显示的值:
这会导致sort 返回[1,2,2,3]。如果排序块是
{ |x,y| y <=> x }
排序块返回这些值:
导致sort 返回[3,2,2,1]。
【讨论】: