Cómo encontrar un mínimo / máximo con Ruby


415

Quiero usar min(5,10), o Math.max(4,7). ¿Hay funciones a este efecto en Ruby?

Respuestas:


723

Tu puedes hacer

[5, 10].min

o

[4, 7].max

Vienen del módulo Enumerable , por lo que todo lo que incluya Enumerabletendrá esos métodos disponibles.

v2.4 presenta los propios Array#miny Array#max, que son mucho más rápidos que los métodos de Enumerable porque omiten las llamadas #each.

@nicholasklick menciona otra opción, Enumerable#minmaxpero esta vez devolviendo una serie de [min, max].

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

3
@kaz No estoy seguro de entender tu comentario.
— Ziggy

3
@Kaz ... ¿te das cuenta de que std::max(4, 7)tiene más "puntuación" que [4, 7].max?
— tckmn

3
@Doorknob Te das cuenta de que std::maxse puede importar a tu espacio de nombres, por lo que simplemente se convierte max(4, 7). Espere; mirando arriba, veo que ya dije eso.
— Kaz

18
La puntuación no es el problema aquí. Una asignación completa del montón para obtener el máximo de algunos valores es la fealdad subyacente aquí.
— kdbanman

77
Ruby es principalmente para el programador, no para la computadora. En palabras de Matz, "espero ver a Ruby ayudar a todos los programadores del mundo a ser productivos, disfrutar de la programación y ser felices. Ese es el propósito principal del lenguaje Ruby". Eso es de la página de Wikipedia en Ruby.
— codificación aaron el

52

Puedes usar

[5,10].min 

o

[4,7].max

Es un método para matrices.


20
Técnicamente es un método para Enumerables, no Arrays.
— Meagar

1
Es un método para matrices con un rendimiento superior al de Enumerable desde v2.4
— Andre Figueiredo

25

Todos esos resultados generan basura en un celoso intento de manejar más de dos argumentos. Me gustaría ver cómo funcionan en comparación con el buen ol:

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

que es, por cierto, mi respuesta oficial a tu pregunta.


Hay algunos rumores que Ruby 2.4 está optimizando [a,b].max, pero aún no está claro si es más rápido que la implementación anterior. blog.bigbinary.com/2016/11/17/…
— Dave Morse

2
esto es micro-optimización, ambos son muy rápidos, la diferencia es insignificante, ver punto de referencia: repl.it/@AndreFigueiredo/DearWeirdSweepsoftware
— Andre Figueiredo

1
¿Este perfil tiene en cuenta el tiempo que se pasa en GC?
— Dave Morse

20

Si necesita encontrar el máximo / mínimo de un hash, puede usar #max_byo#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

Además de las respuestas proporcionadas, si desea convertir Enumerable # max en un método max que pueda invocar un número variable o argumentos, como en otros lenguajes de programación, puede escribir:

def max(*values)
 values.max
end

Salida:

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

Esto abusa de las propiedades del operador splat para crear un objeto de matriz que contenga todos los argumentos proporcionados, o un objeto de matriz vacío si no se proporcionaron argumentos. En el último caso, el método volverá nil, ya que devuelve llamar a Enumerable # max en un objeto de matriz vacío nil.

Si desea definir este método en el módulo matemático, esto debería hacer el truco:

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

Tenga en cuenta que Enumerable.max es, al menos, dos veces más lento en comparación con el operador ternario ( ?:) . Vea la respuesta de Dave Morse para un método más simple y rápido.


¿Pero la reapertura de las clases y módulos estándar no se considera una mala práctica?
— radiantshaw

-2
def find_largest_num(nums)
  nums.sort[-1]
end

ordenar para encontrar el máximo / mínimo es un desperdicio; encontrar min / max es O (n), mientras que la clasificación es O (n log (n)).
— Itamar Mushkin
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.