2016-05-15 10 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:/として配列に

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

や猿、パッチを適用:同じ結果を達成するための別の方法は、このように、group_byを使用することです/stackoverflow.com/questions/22115956 – sawa

+0

ところで、この変数のより一般的な名前は '&block'です。 – Stefan

+0

私は@Stefanに同意します。 'proc'という名前は、ラムダまたは非ラムダProcインスタンスが含まれていると予想されるため、誤解を招きます。 –

答えて

2

callでそれを呼び出すことにより、selectに渡されたブロック内のprocを使用します。

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よりも少し長いですが、この方法では、同じブロックが2つの場所で使用されていることを明確にしています。また、両方のブロックを使用するのが不思議です同じ方法でyieldの暗黙のブロックの受け渡しと&procの明示的な受け渡しを行います。

+0

'proc.call(h)'の代わりに 'yield(h)'を使うこともできます。 – Stefan

+0

ありがとう、ありがとう。 'Proc#yield 'もありますが、それはちょっと混乱しています。 –

+1

'Proc#yield'は混乱していると思いますか?また、(proc === h) 'と' [] 'を使ってprocを呼び出すこともできます(OPで言及されているように、そしてdepcated-but-still-with-us' proc。(h) ') 。 –

1

@DaveSchweisguthは、あなたがリクエストしたようにselectを使用して優れた実装を提案しています。あなたの問題を解決するために、より簡単な方法はここにある

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

それはOPが尋ねたものではありません。しかし、この質問への受け入れられた答えと同じです:http://stackoverflow.com/questions/22115956。 – sawa

関連する問題