如何在方法内使用& proc参数

时间:2016-05-15 04:48:16

标签: ruby

Array#max_by只返回一个值,但我希望所有值都具有最大值。

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参数的值?

2 个答案:

答案 0 :(得分:2)

使用proc调用传递给select的广告块中的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略长,但在这种情况下我更喜欢它,因为它更清楚地表明在方法的两个地方使用了相同的块,并且因为它很奇怪同时使用yield的隐式块传递和同一方法中&proc的显式传递。

答案 1 :(得分: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