Как вы, наверное, уже видели, документация для метода min
говорит:
min(n) → array
min(n) {| a,b | block } → array
Возвращает объект в перечислении с минимальным значением. Первая форма предполагает, что все объекты реализуют Comparable
; второй использует блок для возврата a <=> b
.
Это означает, что в первой форме min
вызывает метод <=>
для объектов в массиве и использует результат, чтобы определить, какой элемент является наименьшим.
Во второй форме min
вместо этого вызывает блок с обоими элементами, которые он хочет сравнить, и использует возвращаемое значение блока, чтобы определить, какой элемент является наименьшим. По сути, он использует блок, как если бы он был реализацией оператора <=>
. Таким образом, 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
.
person
Ajedi32
schedule
04.09.2015