Comment trouver un min / max avec Ruby

415

Je veux utiliser min(5,10), ou Math.max(4,7). Existe-t-il des fonctions à cet effet dans Ruby?

obuzek
la source

Réponses:

723

Tu peux faire

[5, 10].min

ou

[4, 7].max

Ils proviennent du module Enumerable , donc tout ce qui inclut Enumerableaura ces méthodes disponibles.

La v2.4 introduit les méthodes propres Array#minet Array#max, qui sont bien plus rapides que les méthodes d'Enumerable car elles ignorent les appels #each.

@nicholasklick mentionne une autre option, Enumerable#minmaxmais cette fois en retournant un tableau de [min, max].

[4, 5, 7, 10].minmax
=> [4, 10]
theIV
la source
3
@kaz Je ne suis pas sûr de comprendre votre commentaire.
Ziggy
3
@Kaz ... vous vous rendez compte qu'il y std::max(4, 7)a plus de "ponctuation" que [4, 7].max?
tckmn
3
@ Doorknob Vous vous rendez compte que cela std::maxpeut être importé dans votre espace de noms pour qu'il devienne juste max(4, 7). Attendre; en regardant ci-dessus, je vois que je l'ai déjà dit.
Kaz
18
La ponctuation n'est pas le problème ici. Une allocation de tas entière pour obtenir le maximum de quelques valeurs est la laideur sous-jacente ici.
kdbanman
7
Ruby est principalement destiné au programmeur et non à l'ordinateur. Selon les mots de Matz "J'espère voir Ruby aider tous les programmeurs du monde à être productifs, à profiter de la programmation et à être heureux. C'est le but principal du langage Ruby." Ça vient de la page Wikipedia sur Ruby.
codage aaron du
52

Vous pouvez utiliser

[5,10].min 

ou

[4,7].max

C'est une méthode pour les tableaux.

Diego Dias
la source
20
Techniquement, c'est une méthode pour les énumérables, pas les tableaux.
meagar
1
C'est une méthode pour les tableaux avec des performances supérieures à celles d'Enumerable depuis la v2.4
Andre Figueiredo
25

Tous ces résultats génèrent des ordures dans une tentative ardente de gérer plus de deux arguments. Je serais curieux de voir comment ils fonctionnent par rapport aux bons vieux:

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

qui est d'ailleurs ma réponse officielle à votre question.

Dave Morse
la source
Il y a quelques rumeurs que Ruby 2.4 optimise [a,b].max, mais il n'est toujours pas clair si c'est plus rapide que l'implémentation ci-dessus. blog.bigbinary.com/2016/11/17/…
Dave Morse
2
c'est de la micro-optimisation, ils sont tous les deux si rapides, la différence est négligeable, voir benchmark: repl.it/@AndreFigueiredo/DearWeirdSweepsoftware
Andre Figueiredo
1
Ce profilage tient-il compte du temps passé au GC?
Dave Morse
20

Si vous avez besoin de trouver le max / min d'un hachage, vous pouvez utiliser #max_byou#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]
codage aaron
la source
20

En plus des réponses fournies, si vous souhaitez convertir Enumerable # max en une méthode max pouvant appeler un nombre variable ou des arguments, comme dans certains autres langages de programmation, vous pouvez écrire:

def max(*values)
 values.max
end

Production:

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

Cela abuse des propriétés de l'opérateur splat pour créer un objet tableau contenant tous les arguments fournis ou un objet tableau vide si aucun argument n'a été fourni. Dans ce dernier cas, la méthode retournera nil, car l'appel de Enumerable # max sur un objet tableau vide retourne nil.

Si vous souhaitez définir cette méthode sur le module Math, cela devrait faire l'affaire:

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

Notez que Enumerable.max est, au moins, deux fois plus lent que l'opérateur ternaire ( ?:) . Voir la réponse de Dave Morse pour une méthode plus simple et plus rapide.

HamsterMuffin
la source
Mais la réouverture des classes et modules standard n'est-elle pas considérée comme une mauvaise pratique?
radiantshaw
-2
def find_largest_num(nums)
  nums.sort[-1]
end
Almokhtar bekkour
la source
trier pour trouver le maximum / minimum est un gaspillage; trouver min / max est O (n), tandis que le tri est O (n log (n)).
Itamar Mushkin