Как найти мин / макс с Ruby

415

Я хочу использовать min(5,10), или Math.max(4,7). Есть ли функции на этот счет в Ruby?

obuzek
источник

Ответы:

723

Ты можешь сделать

[5, 10].min

или

[4, 7].max

Они приходят из модуля Enumerable , поэтому все, что включает, Enumerableбудет иметь эти методы доступными.

В версии 2.4 представлены собственные Array#minи Array#max, которые намного быстрее методов Enumerable, потому что они пропускают вызовы #each.

@nicholasklick упоминает другой вариант, Enumerable#minmaxно на этот раз возвращает массив [min, max].

[4, 5, 7, 10].minmax
=> [4, 10]
theIV
источник
3
@kaz Я не уверен, что понимаю ваш комментарий.
Зигги
3
@ Kaz ... ты понимаешь, std::max(4, 7)имеет больше "пунктуации", чем [4, 7].max?
tckmn
3
@ Doorknob Вы понимаете, что std::maxможно импортировать в ваше пространство имен, чтобы оно просто стало max(4, 7). Подождите; глядя выше, я вижу, что уже сказал.
Kaz
18
Пунктуация здесь не проблема. Основным уродством здесь является выделение всей кучи, чтобы получить максимум из нескольких значений.
kdbanman
7
Ruby в основном для программиста, а не для компьютера. По словам Матца: «Я надеюсь, что Ruby поможет каждому программисту в мире быть продуктивным, получать удовольствие от программирования и быть счастливым. Это основная цель языка Ruby». Это со страницы Википедии на Ruby.
Аарон-кодирование
52

Ты можешь использовать

[5,10].min 

или

[4,7].max

Это метод для массивов.

Диего Диас
источник
20
Технически это метод для Enumerables, а не для Array.
Meagar
1
Это метод для массивов с превосходной производительностью по сравнению с Enumerable начиная с версии 2.4
Andre Figueiredo
25

Все эти результаты создают мусор в ревностной попытке обработать более двух аргументов. Мне было бы любопытно посмотреть, как они работают по сравнению с хорошими оль:

def max (a,b)
  a>b ? a : b
end

кстати, мой официальный ответ на ваш вопрос.

Дейв Морс
источник
Есть некоторые грохоты, которые оптимизирует Ruby 2.4 [a,b].max, но все еще неясно, быстрее ли это, чем приведенная выше реализация. blog.bigbinary.com/2016/11/17/…
Дейв Морс
2
это микрооптимизация
Andre Figueiredo
1
Учитывает ли это профилирование время, проведенное в GC?
Дейв Морс
20

Если вам нужно найти максимум / мин хеша, вы можете использовать #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]
Aaron-кодирования
источник
20

В дополнение к предоставленным ответам, если вы хотите преобразовать Enumerable # max в метод max, который может вызывать переменное число или аргументы, как в некоторых других языках программирования, вы можете написать:

def max(*values)
 values.max
end

Вывод:

max(7, 1234, 9, -78, 156)
=> 1234

Это нарушает свойства оператора splat для создания объекта массива, содержащего все предоставленные аргументы, или пустого объекта массива, если аргументы не были предоставлены. В последнем случае метод вернется nil, так как вызов Enumerable # max для пустого объекта массива возвращает nil.

Если вы хотите определить этот метод в модуле Math, это должно помочь:

module Math
 def self.max(*values)
  values.max
 end
end

Обратите внимание, что Enumerable.max, по крайней мере, в два раза медленнее по сравнению с троичным оператором ( ?:) . Смотрите ответ Дейва Морса для более простого и быстрого метода.

HamsterMuffin
источник
Но разве повторное открытие стандартных классов и модулей не считается плохой практикой?
Radiantshaw
-2
def find_largest_num(nums)
  nums.sort[-1]
end
Альмохтар беккур
источник
сортировка по максимуму / минимуму расточительна; нахождение мин / макс - O (n), а сортировка - O (n log (n)).
Итамар Мушкин