2016-05-15 41 views
2

Array#max_by只返回一個值,但我想讓所有具有最大值的值。如何在方法內使用&proc參數

hashes = [{a: 1, b:2}, {a:2, b:3}, {a:1, b:3}] 
max = hashes.map{|h| h[:b]}.max 
hashes.select{|h| h[:b] == max} 
# => [{a: 2, b: 3}, {a: 1, b: 3}] 

此代碼工作正常,我想將它添加到Array類。

class Array 
    def max_values_by(&proc) 
    max = map(&proc).max 
    # I don't know how to use `select` here. 
    end 
end 

如何訪問&proc參數的值?

+1

解決你的問題更直接的方式是在這裏:HTTP:/ /stackoverflow.com/questions/22115956。 – sawa

+0

順便說一下,'&block'是這個變量的一個更常見的名稱。 – Stefan

+0

我同意@Stefan。使用'proc'這個名字會引起誤解,因爲可能期望它包含lambda或非lambda Proc實例。 –

回答

2

使用在傳遞給select塊中的proc通過用call調用它:

class Array 
    def max_values_by(&proc) 
    max = map(&proc).max 
    select { |h| proc.call(h) == max } 
    end 
end 
hashes.max_values_by { |h| h[:b] } 
=> [{a: 2, b: 3}, {a: 1, b: 3}] 

yield,其給出了相同的結果:

def max_values_by(&proc) 
    max = map(&proc).max 
    select { |h| yield(h) == max } 
end 

雖然proc.callyield稍長,在這種情況下,我更喜歡它,因爲它更清楚地表明在該方法的兩個地方使用了同一個塊,並且因爲使用i以相同方法通過yield和明確通過&proc

+0

你也可以用'yield(h)'代替'proc.call(h)' – Stefan

+0

補充,謝謝。還有'Proc#yield',但這只是令人困惑。 –

+1

您認爲'Proc#yield'令人困惑?你也可以用'(proc === h)'(和'[]'來調用proc,就像OP所說的那樣,並且用depricated-but-still-with-us'proc。(h)') 。 –

1

@DaveSchweisguth建議使用select,如您所要求的一個很好的實施。達到相同的結果的另一種方法是使用group_by,像這樣:

>> hashes.group_by{|h| h[:b]}.max.last 
=> [{:a=>2, :b=>3}, {:a=>1, :b=>3}] 

或猴子打補丁到數組爲:

class Array 
    def max_values_by(&proc) 
    group_by(&proc).max.last 
    end 
end 
+0

這不是OP要求的。但是與這個問題的接受答案相同:http://stackoverflow.com/questions/22115956。 – sawa

相關問題