Ruby Array#sort 如何知道块应该按升序或降序排序

Jig*_*hel 2 ruby sorting

相关问题已在/sf/answers/799950791/上提供,但我想了解的是

使用时

a.sort { |x, y| x <=> y } 
Run Code Online (Sandbox Code Playgroud)

它如何知道该块应按升序排序,并且在使用时类似

a.sort { |x, y| y <=> x } 
Run Code Online (Sandbox Code Playgroud)

它如何知道这个块应该按降序排序?我很困惑,因为这两个块都使用宇宙飞船运算符,并且预计在每次比较期间返回以下内容,以防出现以下情况a.sort { |x, y| x <=> y }

  • -1 如果 x < y
  • 0 如果 x == y
  • 1 如果 x > y

并在每次比较期间进行以下情况a.sort { |x, y| y <=> x }

  • -1 如果 y < x
  • 0 如果 y == x
  • 1 如果 y > x

现在我们来看一个数组示例:

2.3.2 :023 > a = [ "d", "a", "e", "c", "b" ]
 => ["d", "a", "e", "c", "b"]
Run Code Online (Sandbox Code Playgroud)

当我们使用a.sort { |e1, e2| p [e1, e2]; e1 <=> e2 }以下方法对其进行排序时,结果是:

["d", "a"] (cmp result: 1)
["c", "b"] (cmp result: 1)
["e", "b"] (cmp result: 1)
["e", "c"] (cmp result: 1)
["a", "b"] (cmp result: -1)
["d", "b"] (cmp result: 1)
["d", "c"] (cmp result: 1)
["d", "e"] (cmp result: -1)
 => ["a", "b", "c", "d", "e"]
Run Code Online (Sandbox Code Playgroud)

现在在这种情况下,它如何知道“a”要放在第一位,然后是“b”,然后是“c”,等等?

同样,当我们使用a.sort { |e1, e2| p [e2, e1]; e2 <=> e1 }以下方法对其进行排序时,结果是:

["a", "d"] (cmp result: -1)
["b", "c"] (cmp result: -1)
["c", "e"] (cmp result: -1)
["e", "d"] (cmp result: 1)
["c", "d"] (cmp result: -1)
["c", "a"] (cmp result: 1)
["b", "a"] (cmp result: 1)
 => ["e", "d", "c", "b", "a"]
Run Code Online (Sandbox Code Playgroud)

那么在这种情况下,它如何知道“e”要放在第一位,然后是“d”,然后是“c”,等等?考虑到两个块中两个元素的比较应该返回 1、0 或 -1?

Dav*_*son 5

块返回的值告诉sort哪个元素在列表中排在第一位。如果该块返回1,则意味着第一个块参数将被视为“大于”第二个块参数,因此第一个块参数必须位于排序结果中的第二个块参数之后。

一件有趣的事情是,Ruby 的sort算法利用了比较的传递属性:在第一个示例中,它从未直接比较“a”和“c”,但它的其他比较表明“a”<“b”和“b” " < "c" 因此它在结果中将 "c" 放在 "a" 之后。

该表达式y <=> x相当于-(x <=> y)(假设两个对象的类都实现了合理的太空飞船运算符)。因此,如果您按 排序y <=> x,则所有单独的比较都会反转,并且排序后的数组必须采用相反的顺序。