Як знайти хв / макс з Ruby


415

Я хочу використовувати min(5,10), або Math.max(4,7). Чи є функції в цьому ефекті у Рубі?

Відповіді:


722

Ви можете зробити

[5, 10].min

або

[4, 7].max

Вони надходять з модуля « Численні» , тому все, що включає Enumerable, матиме ці методи.

v2.4 представляє власні Array#minта Array#max, які набагато швидші, ніж методи Enumerable, оскільки вони пропускають виклики #each.

@nicholasklick згадує інший варіант, Enumerable#minmaxале цього разу повертає масив [min, max].

[4, 5, 7, 10].minmax
=> [4, 10]

3
@kaz Я не впевнений, що я розумію ваш коментар.
Ziggy

3
@Kaz ... ти розумієш, std::max(4, 7)має більше "пунктуацій", ніж [4, 7].max?
tckmn

3
@Doorknob Ви розумієте, що std::maxїх можна імпортувати у ваш простір імен, щоб він просто став max(4, 7). Зачекайте; дивлячись нагорі, я бачу, що я це вже сказав.
Каз

18
Пунктуація - це не проблема. Ціле виділення купи, щоб отримати максимум декількох значень, є основою неподобства тут.
kdbanman

7
Рубі в основному для програміста, а не для комп'ютера. За словами Маца, "я сподіваюся, що Рубі допоможе кожному програмісту у світі бути продуктивним, насолоджуватися програмуванням і бути щасливим. Це головна мета мови Ruby". Це зі сторінки Вікіпедії на Рубі.
кодування

52

Можна використовувати

[5,10].min 

або

[4,7].max

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


20
Технічно це метод для перелічувачів, а не масивів.
meagar

1
Це метод для масивів з вищою продуктивністю над Enumerable's з версії 2.4
Андре Фігейредо

25

Усі ці результати генерують сміття в ревній спробі обробити більше двох аргументів. Мені буде цікаво побачити, як вони працюють у порівнянні з хорошими 'ol:

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

це, до речі, моя офіційна відповідь на ваше запитання.


Існують певні бурчання, які оптимізує Ruby 2.4 [a,b].max, але все ще не ясно, чи швидше це, ніж вищевказана реалізація. blog.bigbinary.com/2016/11/17/…
Дейв Морз

2
це мікрооптимізація, вони обоє настільки швидкі, різниця незначна, див. орієнтир: repl.it/@AndreFigueiredo/DearWeirdSweepsoftware
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]

20

На додаток до наданих відповідей, якщо ви хочете перетворити Численні # 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 є, щонайменше, удвічі повільніше порівняно з потрійним оператором ( ?:) . Дивіться відповідь Дейва Морзе про більш простий і швидкий метод.


Але чи не повторне відкриття стандартних класів і модулів не вважається поганою практикою?
радіантшоу

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.