簡體   English   中英

Ruby Array#sort 它如何知道塊應該按升序或降序排序

[英]Ruby Array#sort how it knows that the block should sort in ascending or descending order

https://stackoverflow.com/a/11427868/936494已經提供了一個相關問題,但我想了解的是

使用時

a.sort { |x, y| x <=> y } 

它如何知道這個塊應該按升序排序,並且在使用時類似

a.sort { |x, y| y <=> x } 

它怎么知道這個塊應該按降序排序? 我很困惑,因為這兩個塊都使用了 spaceship 運算符,並且在a.sort { |x, y| x <=> y }的情況下,預計在每次比較期間都會返回以下內容a.sort { |x, y| x <=> y }

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

並在a.sort { |x, y| y <=> x }的情況下進行每次比較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"]

當我們使用a.sort { |e1, e2| p [e1, e2]; e1 <=> e2 }對其進行排序時a.sort { |e1, e2| p [e1, e2]; e1 <=> e2 } 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"]

現在在這種情況下,它如何知道將“a”放在第一位,然后是“b”,然后是“c”,等等?

同樣,當我們使用a.sort { |e1, e2| p [e2, e1]; e2 <=> e1 }對其進行排序時a.sort { |e1, e2| p [e2, e1]; e2 <=> e1 } 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"]

那么在這種情況下,它是如何知道將“e”放在第一位,然后是“d”,然后是“c”等等? 並且考慮到兩個塊中兩個元素的比較應該返回 1、0 或 -1 的事實?

塊返回的值告訴sort哪個元素在列表中排在第一位。 如果塊返回1 ,則意味着第一個塊參數將被視為“大於”第二個塊參數,因此第一個塊參數必須在排序結果中的第二個之后。

一個有趣的事情是 Ruby 的sort算法利用了比較的傳遞性:在您的第一個示例中,它從未直接比較 "a" 和 "c",但它的其他比較表明 "a" < "b" 和 " b" < "c" 所以它在結果中將 "c" 放在 "a" 之后。

表達式y <=> x等價於-(x <=> y) (假設兩個對象的類都實現了一個合理的宇宙飛船運算符)。 因此,如果您按y <=> x排序,則所有單獨的比較都會被反轉,並且排序后的數組必須以相反的順序排列。

它怎么知道“e”被放在第一位,然后是“d”,然后是“c”

從比較器塊,就是這樣。 在您自己的示例中: ["a", "d"] (cmp result: -1) 這個 -1 告訴排序"d"應該在"a"之前。 它稍后將"d""e"進行比較,得到 1 並得知"d"應該在"e"之后。 等等。

使用時

a.sort { |x, y| x <=> y }

它如何知道這個塊應該按升序排序

Array#sort知道這一點。 該塊只是告訴Array#sort兩個元素中的哪個“小於”另一個元素。 而已。

換句話說:它是定義“升序”含義的

同樣在使用時

a.sort { |x, y| y <=> x }

它怎么知道這個塊應該按降序排序?

不是按降序排列的。 它按照塊中實現的排序關系定義的升序排列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM