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