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

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


person obuzek    schedule 31.08.2009    source источник


Ответы (5)


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

[5, 10].min

or

[4, 7].max

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

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

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

[4, 5, 7, 10].minmax
=> [4, 10]
person theIV    schedule 31.08.2009
comment
Спасибо @nicholasklick, только что обновил свой ответ. Даже не знал, что существует! - person theIV; 30.04.2013
comment
Common Lisp: (defun minmax (&rest args) (values (apply #'min args) (apply #'max args))) Теперь: (minmax 3 4 5 7 1 9 2) возвращает два возвращаемых значения: 1 и 9. - person Kaz; 22.02.2014
comment
@kaz Я не уверен, что понимаю ваш комментарий. - person Ziggy; 23.02.2014
comment
@Kaz ... ты понимаешь, что в std::max(4, 7) знаков препинания больше, чем в [4, 7].max? - person tckmn; 25.03.2014
comment
@Doorknob Вы понимаете, что std::max можно импортировать в ваше пространство имен, так что оно становится просто max(4, 7). Ждать; посмотрев выше, я вижу, что уже сказал это. - person Kaz; 25.03.2014
comment
@Kaz Хорошо, тогда такое же количество знаков препинания. В любом случае, я считаю, что знаки препинания ни для чего не подходят. - person tckmn; 25.03.2014
comment
Пунктуация здесь не проблема. Распределение всей кучи для получения максимума из нескольких значений является основным уродством здесь. - person kdbanman; 08.03.2015
comment
Не забудьте сначала очистить массив, удалив нулевые значения или значения, которые нельзя сравнивать. - person Cyril Duchon-Doris; 16.06.2015
comment
Ruby в основном предназначен для программистов, а не для компьютера. По словам Матца, я надеюсь, что Ruby поможет каждому программисту в мире быть продуктивным, получать удовольствие от программирования и быть счастливым. Это основная цель языка Ruby. Это со страницы Википедии о Ruby. - person aaron-coding; 03.11.2015
comment
@ aaron-coding Что ж, помощь программисту в написании неэффективного кода ему не совсем помогает. ;) Но да - я знаю, что в многих случаях эти микрооптимизации не имеют значения. Однако я думаю, что в Ruby есть основная проблема, поощряющая неэффективность. Эффективность - не самая сильная сторона или цель дизайна Ruby; у него другие, более красноречивые ценности. - person Per Lundberg; 31.10.2017
comment
@Kaz Хороший алгоритм Common Lisp, но неэффективный. - person Fernando Pelliccioni; 05.07.2019

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

[5,10].min 

or

[4,7].max

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

person Diego Dias    schedule 31.08.2009
comment
Технически это метод Enumerables, а не Arrays. - person meagar; 13.12.2013
comment
Это метод для массивов с превосходной производительностью по сравнению с Enumerable начиная с v2.4. - person Andre Figueiredo; 03.07.2018

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

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

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

person Dave Morse    schedule 10.01.2016
comment
Есть некоторые слухи, что Ruby 2.4 оптимизирует [a,b].max, но до сих пор не ясно, быстрее ли это, чем описанная выше реализация. blog.bigbinary. ru / 2016/11/17 / - person Dave Morse; 27.05.2017
comment
это микрооптимизация, они оба такие быстрые, разница незначительна, см. тест: repl.it/ @ AndreFigueiredo / DearWeirdSweepsoftware - person Andre Figueiredo; 03.07.2018
comment
Учитывает ли это профилирование время, проведенное в сборке мусора? - person Dave Morse; 06.07.2018

Если вам нужно найти максимальное / минимальное значение хэша, вы можете использовать #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]
person aaron-coding    schedule 24.07.2015

В дополнение к предоставленным ответам, если вы хотите преобразовать 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, по крайней мере, в два раза медленнее по сравнению с тернарным оператором (?:). См. ответ Дэйва Морса для более простого и быстрого метода.

person Community    schedule 20.09.2014
comment
Но не считается ли повторное открытие стандартных классов и модулей плохой практикой? - person radiantshaw; 16.08.2018