Ruby 如何使用&;方法内的proc参数

Ruby 如何使用&;方法内的proc参数,ruby,Ruby,Array#max_by只返回一个值,但我希望所有值都具有max值 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)

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

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

使用传递给
的块中的
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}]
或使用
产量
,得出相同的结果:

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

虽然
proc.call
yield
稍长一点,但我更喜欢在这种情况下使用它,因为它更清楚地表明,相同的块在方法中的两个位置使用,因为在同一方法中同时使用
yield
的隐式块传递和
&proc
的显式传递是很奇怪的。

@daveshweisguth建议按照您的要求使用
select
来实现。实现相同结果的另一种方法是使用
group\u 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

解决问题的一个更直接的方法是:。顺便说一句,
&block
是这个变量更常见的名称。我同意@Stefan。使用名称
proc
会产生误导,因为人们可能会认为它包含lambda或非lambda proc实例。OP不是这样要求的。但与此问题的公认答案相同:。您也可以使用
yield(h)
而不是
proc.call(h)
添加,谢谢。还有
Proc#yield
,但那只是令人困惑。你认为
Proc#yield
令人困惑吗?你也可以用
(proc==h)
(和
[]
)调用proc,正如OP所提到的,还有被除锈但仍与我们在一起的
proc.(h)
)。@CarySwoveland我不知道
)被弃用了。我在谷歌上搜索了一下,但什么也找不到。你能告诉我在哪里可以找到更多关于它的信息吗?@Keith,也许我错了。我以为我读过,但找不到参考资料
Proc#()
在v2.2.0中未作为实例方法列出,但该文档还声明,“prc()使用给定的参数调用prc.call()。这是隐藏“call”的语法。