web-dev-qa-db-fra.com

Comment trouvez-vous un min / max avec Ruby?

Je veux faire quelque chose de simple et direct, comme min(5,10) ou Math.max(4,7). Existe-t-il des fonctions à cet effet dans Ruby?

391
obuzek

Tu peux faire

_[5, 10].min
_

ou

_[4, 7].max
_

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

la v2.4 introduit ses propres _Array#min_ et _Array#max_, qui sont bien plus rapides que les méthodes d’Enumerable car ils ignorent l’appel _#each_.

EDIT

@nicholasklick mentionne une autre option, Enumerable#minmax , mais renvoie cette fois un tableau de _[min, max]_.

_[4, 5, 7, 10].minmax
=> [4, 10]
_
679
theIV

Vous pouvez utiliser

[5,10].min 

ou

[4,7].max

C'est une méthode pour les tableaux.

51
Diego Dias

Tous ces résultats génèrent des déchets dans une tentative zélée de gérer plus de deux arguments. Je serais curieux de voir comment ils se comportent par rapport au bon vieux:

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

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

22
Dave Morse

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 d'autres langages de programmation, vous pouvez écrire:

def max(*values)
 values.max
end

Sortie:

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

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

Si vous voulez 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 réponse de Dave Morse pour une méthode plus simple et plus rapide.

20
HamsterMuffin

Si vous avez besoin de trouver le max/min d'un hachage, vous pouvez utiliser #max_by ou #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]
17
aaron-coding