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.