Ruby 组合比较运算符 (<=>) 和 min / max / minmax 函数

1 ruby max min logical-operators minmax

我理解#max、#min、#minmax。我明白<=>。但它如何在这些函数之一的块中工作呢?

也就是说,下面第三行发生了什么?#min <=> 在做什么?

a = %w(albatross dog horse)
a.min                                   #=> "albatross"
a.min { |a, b| a.length <=> b.length }  #=> "dog"
Run Code Online (Sandbox Code Playgroud)

来自http://ruby-doc.org/core-2.2.3/Enumerable.html#method-i-min的示例

对于数字数组它会有什么行为?

Aje*_*i32 6

正如您可能已经看到的,该方法的文档min说:

\n\n
\n

min(n) \xe2\x86\x92 array

\n\n

min(n) {| a,b | block } \xe2\x86\x92 array

\n\n

返回枚举中具有最小值的对象。第一种形式\n 假设所有对象都实现Comparable; 第二个使用块来\n return a <=> b

\n
\n\n

这意味着,在第一种形式中,min调用<=>数组中对象的方法并使用结果来确定哪个元素是最小的。

\n\n

在第二种形式中,min而是调用具有要比较的两个元素的,并使用块的返回值来确定哪个元素是最小的。基本上,它使用块就像它是运算符的实现一样<=>。所以x.min {|a,b| a <=> b }相当于x.min.

\n\n

在给定的示例 ( a.min { |a, b| a.length <=> b.length } #=> "dog") 中,这意味着不是比较每个元素来确定排序顺序,而是比较每个元素的长度来做出决定。由于"dog"是列表中最短的字符串,因此它就是 . 返回的值minmaxminmax、 和sort行为类似。

\n\n

请注意,该示例有点做作,因为您可以min_by在这种情况下使用更简单的代码来实现相同的结果:a.min_by { |x| x.length }。如果您在确定排序顺序时想要更细粒度的控制,则使用min块可能是合适的。

\n\n
\n

对于数字数组它会有什么行为?

\n
\n\n

min无论数组包含什么,其行为方式都相同。在这种情况下,尽管使用块{ |a, b| a.length <=> b.length }不起作用,因为数字没有length方法。这是一个更好的数字示例,它按最小到最大排序,但始终将奇数计算为大于偶数:

\n\n
[2, 10, 9, 7, 6, 1, 5, 3, 8, 4].sort do |a, b|\n  if a.odd? && b.even?\n    1\n  elsif a.even? && b.odd?\n    -1\n  else\n    a <=> b\n  end\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果:

\n\n
[2, 4, 6, 8, 10, 1, 3, 5, 7, 9]\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意最终数组中偶数如何排序在奇数之前?这是我们传递给 的块的结果sortminmax和的行为类似minmax

\n