您可能已经看到,the documentation 的 min 方法说:
min(n) → array
min(n) {| a,b | block } → array
返回枚举中具有最小值的对象。第一种形式
假设所有对象都实现Comparable;第二个使用块
返回a <=> b。
这意味着,在第一种形式中,min 正在对数组中的对象调用 <=> 方法,并使用结果来确定哪个元素是最小的。
在第二种形式中,min 调用 block 与它想要比较的两个元素,并使用块的返回值来确定哪个元素是最小的。基本上,它使用该块,就好像它是 <=> 运算符的实现一样。所以x.min {|a,b| a <=> b } 将等同于x.min。
在给出的示例 (a.min { |a, b| a.length <=> b.length } #=> "dog") 中,这意味着不是比较每个元素来确定排序顺序,而是比较每个元素的 长度 来确定。由于"dog" 是列表中最短的字符串,这就是min 返回的值。 max、minmax 和 sort 的行为类似。
请注意,这里的示例有点做作,因为在这种情况下您可以使用min_by 以使用更简单的代码实现相同的结果:a.min_by { |x| x.length }。如果您在确定排序顺序时想要更细粒度的控制,使用带有块的min 可能是合适的。
对于数字数组会有什么行为?
min 的行为方式相同,无论数组包含什么。在这种情况下,尽管使用块 { |a, b| a.length <=> b.length } 不起作用,因为数字上没有 length 方法。这是一个更好的数字示例,它按从小到大排序,但始终将奇数视为大于偶数:
[2, 10, 9, 7, 6, 1, 5, 3, 8, 4].sort do |a, b|
if a.odd? && b.even?
1
elsif a.even? && b.odd?
-1
else
a <=> b
end
end
结果:
[2, 4, 6, 8, 10, 1, 3, 5, 7, 9]
注意在最终数组中偶数如何排在奇数之前?这是我们传递给sort 的块的结果。 min、max 和 minmax 的行为类似。