如何使用 Ruby 找到最小值/最大值
Posted
技术标签:
【中文标题】如何使用 Ruby 找到最小值/最大值【英文标题】:How to find a min/max with Ruby 【发布时间】:2010-11-24 11:13:15 【问题描述】:我想使用min(5,10)
或Math.max(4,7)
。 Ruby 中有没有实现这种效果的函数?
【问题讨论】:
【参考方案1】:你可以的
[5, 10].min
或
[4, 7].max
它们来自Enumerable module,因此包括Enumerable
在内的任何东西都可以使用这些方法。
v2.4 引入了自己的 Array#min
和 Array#max
,它们比 Enumerable 的方法快得多,因为它们跳过了调用 #each
。
@nicholasklick 提到了另一个选项 Enumerable#minmax
,但这次返回的是一个 [min, max]
数组。
[4, 5, 7, 10].minmax
=> [4, 10]
【讨论】:
@kaz 我不确定我是否理解您的评论。 @Kaz ...你意识到std::max(4, 7)
比[4, 7].max
有更多的“标点符号”?
@Doorknob 你确实意识到std::max
可以被导入你的命名空间,所以它就变成了max(4, 7)
。等待;看上面,我知道我已经说过了。
标点符号不是这里的问题。获得几个值的最大值的整个堆分配是这里潜在的丑陋。
Ruby 主要面向程序员而非计算机。用 Matz 的话来说,“我希望看到 Ruby 帮助世界上的每一位程序员提高工作效率,享受编程并获得快乐。这就是 Ruby 语言的主要目的。”来自 Ruby 上的 Wikipedia 页面。【参考方案2】:
你可以使用
[5,10].min
或
[4,7].max
这是一个数组的方法。
【讨论】:
从技术上讲,这是一种用于枚举的方法,而不是数组。 自 v2.4 起,这是一种性能优于 Enumerable 的数组方法【参考方案3】:除了提供的答案之外,如果您想将Enumerable#max 转换为可以调用变量数或参数的 max 方法,就像在其他一些编程语言中一样,您可以编写:
def max(*values)
values.max
end
输出:
max(7, 1234, 9, -78, 156)
=> 1234
这会滥用 splat 运算符的属性来创建一个包含所有提供的参数的数组对象,如果没有提供参数,则创建一个空数组对象。在后一种情况下,该方法将返回nil
,因为在空数组对象上调用Enumerable#max 会返回nil
。
如果你想在数学模块上定义这个方法,这应该可以解决问题:
module Math
def self.max(*values)
values.max
end
end
请注意,Enumerable.max 至少是 two times slower compared to the ternary operator (?:
)。请参阅Dave Morse's answer 了解更简单、更快捷的方法。
【讨论】:
但是重新打开标准类和模块不是一种不好的做法吗?【参考方案4】:如果您需要找到哈希的最大值/最小值,可以使用#max_by
或#min_by
people = 'joe' => 21, 'bill' => 35, 'sally' => 24
people.min_by |name, age| age #=> ["joe", 21]
people.max_by |name, age| age #=> ["bill", 35]
【讨论】:
【参考方案5】:所有这些结果都在热心地尝试处理两个以上的参数时产生垃圾。我很想知道他们与优秀的 ol 相比表现如何:
def max (a,b)
a>b ? a : b
end
顺便说一下,这是我对你问题的正式回答。
【讨论】:
有传言说 Ruby 2.4 正在优化[a,b].max
,但目前还不清楚它是否比上述实现更快。 blog.bigbinary.com/2016/11/17/…
这是微优化,它们都非常快,差异可以忽略不计,请参阅基准:repl.it/@AndreFigueiredo/DearWeirdSweepsoftware
此分析是否考虑了在 GC 中花费的时间?【参考方案6】:
def find_largest_num(nums)
nums.sort[-1]
end
【讨论】:
以上是关于如何使用 Ruby 找到最小值/最大值的主要内容,如果未能解决你的问题,请参考以下文章