如何有用的是Object#<=>爲nil
?我認爲這隻受到人們的想象力的限制。
實施例#1
下面是如何可以是有用的行人的例子。假設你想對數組進行排序:
arr = [1,nil,3,nil,2]
所有的nil
來臨了第一,所以它會返回:
[nil, nil, 1, 2, 3]
由於:
nil<=>nil #=> 0
,併爲所有非nil
物體a
:
nil<=>x #=> nil
x<=>nil #=> nil
,我們可以這樣寫:
arr.sort { |a,b| (a<=>b) ? a<=>b : a.nil? ? -1 : 1 }
#=> [nil, nil, 1, 2, 3]
例2
現在讓我們來看看這是更有趣的第二個例子。假設我們有超賣門票的戲劇表演,必須拒絕一些顧客,並給他們退款。哈希tickets
顯示了他們的票付出什麼每個人:
ticket_holders = { 'bob'=>10, 'lucy'=>15, 'cher'=>5, 'arnold'=>12 }
我們希望最小化發行的退款,但不希望從轉身離開名人的負面宣傳,由下式給出:
celebrities = ['arnold', 'cher']
所以我們會給他們最高的偏好。因此,我們希望按降序對ticket_holders
進行排序,除了我們希望鍵爲celebrities
之前的鍵值對。也就是說,我們希望得到的結果是:
['cher', 'arnold', 'lucy', 'bob']
或
['arnold', 'cher', 'lucy', 'bob']
我們去一個通用的解決方案:
module Enumerable
def sort_by_nils_first
sort do |a,b|
av = yield(a)
bv = yield(b)
(av<=>bv) ? av<=>bv : av.nil? ? -1 : 1
end
end
end
我們因此適用:
ticket_holders.sort_by_nils_first { |name,price|
celebrities.include?(name) ? nil : -price }.map(&:first)
#=> ["arnold", "cher", "lucy", "bob"]
僅考慮celebriti的數量在這個世界上,以及如何對待他們,我認爲這是一個非常有用的方法。
應用到前面的例子中,我們得到:
[1,nil,3,nil,2].sort_by_nils_first(&:itself)
#=> [nil, nil, 1, 2, 3]
,我已經使用從V2.2 Object#itself。
sort_by_nils_first
當然可以修改爲當沒有給出塊時返回Enumerator
,以使其與Enumerable#sort_by相當。
那麼解釋行爲。在你看來,有沒有一種情況是有用的?或者,這僅僅是任何語言的陷阱之一? – kdbanman 2015-03-08 20:02:47
我認爲這是微不足道的;它的存在使得如果你對於事情的表現應該有不同的意見,那麼你可以實現這些意見,但我同意在大多數情況下它通常沒有用。 – 2015-03-08 20:05:12