返回参数的名称而不是其值 - Ruby

3

我需要打印出一个 .max 函数的结果,但显示它的参数名称,而不是被 .max 方法使用的目标值(数字)。

def who_is_bigger(a,b,c)
  "#{[a,b,c].max} is bigger"
end

预期结果:

expect(who_is_bigger(84, 42, 21)).to eq("a is bigger")
expect(who_is_bigger(42, 84, 21)).to eq("b is bigger")
expect(who_is_bigger(42, 21, 84)).to eq("c is bigger")
2个回答

3
据我所知,没有一种轻松或易于理解的方法可以从其值中获取参数的名称。(有关如何进行此操作的一种方式,请参见答案底部。)
相反,这是我会做的方式,我认为它很好并且易读:
def who_is_bigger(a,b,c)
  values = {a: a, b: b, c: c}
  largest_key, _ = values.max_by { |key, value| value }
  "#{largest_key} is bigger"
end

这里是工作原理:

  1. 使用参数构建哈希表,并将其存储在 values中。例如,该哈希表可以是{ a: 84, b: 42, c: 21 }
  2. 使用 Enumerable#max_by方法在哈希表中查找最大值。这将在largest_pair中存储两个项的数组,例如 [:a, 84]。注意我们想要的密钥是第一项,因此我们使用解构提取该对的第一项并将其存储在largest_key中。

  3. 构建字符串并从方法中返回。


如果您希望以一种动态访问和迭代参数名称和值的方式来完成此操作,您可以使用如下代码:

def who_is_bigger(a,b,c)
  params = method(__method__).parameters
  values = params.map { |_, name| [name, binding.local_variable_get(name)] }.to_h
  largest_key, _ = values.max_by { |key, value| value }
  "#{largest_key} is bigger"
end

我认为这种方法有点粗糙,比另一种解决方案更难读懂。


2
你可以使用 largest_key, largest_value = values.max_by { ... } 将键和值分别赋给不同的变量。 - Stefan
啊,是的,那看起来会更清晰! - Aaron Christiansen
您的第一句话表明有一种方法可以从值中获取名称,尽管这很难理解或需要付出努力。如果您知道这是真的,那么您应该至少概述该过程;如果您不知道这是真的,您不应该建议它。此外,“really”在“there's not really...”中是什么意思?请准确说明! - Cary Swoveland
@CarySwoveland 理得啦 - 已添加至回答底部。 - Aaron Christiansen

2

以下是使用 Ruby 的 Bindingmax_by 方法进行的另一种方法:

def who_is_bigger(a, b, c)
  biggest = binding.local_variables.max_by do |v|
              binding.local_variable_get(v) || -Float::INFINITY
            end
  "#{biggest} is biggest"
end

who_is_bigger(10, 21, 30)
=> "c is biggest"

who_is_bigger(40, 31, 30)
=> "a is biggest"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接