Pregunta

Vamos a decir que tengo la siguiente matriz:

arr = [[5, 1], [2, 7]]

y yo quiero encontrar el elemento mínimo, comparando el segundo elemento de los elementos. El elemento mínima será [5, 1] desde 1 es menor que 7. Puedo usar el siguiente código:

arr.min {|a,b| a[1] <=> b[1]}

Para el cálculo de la máxima, que puede hacer lo mismo:

arr.max {|a,b| a[1] <=> b[1]}

Esto da [2, 7].

Yo uso el mismo bloque todo el tiempo. Me gustaría tener ese bloque en algún lugar y proporcionarla a la función de mínimo / máximo. Yo esperaba algo como:

blo = lambda {|a,b| a[1] <=> b[1]}
arr.min blo

funcionaría, pero no fue así. Alguna idea sobre cómo puedo hacer esto?

¿Fue útil?

Solución

Use el operador & para girar un objeto Proc en un bloque.

arr.min &blo

Otros consejos

respuesta

@ de sepp2k es el más general, pero en su caso concreto, me gustaría simplemente utilizar

arr.min_by(&:last)
arr.max_by(&:last)

ya que es más más evidente que todos esos llaves y corchetes y los índices de matriz flotando alrededor.

Si todo lo que necesita es mínima y máxima, podría utilizar Enumerable#minmax método y calcular tanto a la vez:

min, max = arr.minmax {|a,b| a[1] <=> b[1]}
#=> [[5, 1], [2, 7]]
min
#=> [5, 1]
max
#=> [2, 7]

Editar: Hell, sólo se dio cuenta de que también es minmax_by, por lo que se puede combinar con el método last, y tienen:

min, max = arr.minmax_by &:last

¿qué tal esto?

=> [[5, 4], [9, 5], [2, 7]]
>> arr.sort!{|x,y| x[1]<=>y[1] }
=> [[5, 4], [9, 5], [2, 7]]
>> min,max=arr[0],arr[-1]
=> [[5, 4], [2, 7]]

Una solución más general a problemas como esto es para evitar matrices anidadas por completo y utilizar una clase en su lugar. A continuación, puede definir el <=> operador para esa clase, que le da acceso a todas las funciones en el mixin Comparable (http://ruby-doc.org/core/classes/Comparable.html) le da la <, <= , ==,> =, y> operadores y el método 'entre?'

Esto es sólo un ejemplo, en la vida real que usaría clases que describen lo que la tienda:

class Duo

  include Comparable

  def initialize( a, b )
      @a = a
      @b = b
  end

  def <=>(rhs)
      @b <=> rhs.b
  end

end

Si usted tiene una serie de Duo oponerse a continuación, puede utilizar los minutos, y funciones de clasificación máximo sin tener que definir el operador de comparación. Así que ...

@a = Duo.new( 1, 10 )
@b = Duo.new( 2, 5 )
@c = Duo.new( 3, 1 )

[ @a, @b, @c ].sort

devolvería el array [@c, @b, @a]

y

[@a, @b, @c].max

volvería @a

Esto es mucho más la 'Rubí Way' de anidada estructuras de datos con la lógica que se basa en las posiciones en las matrices. Se tarda un poco más de trabajo al principio, pero lo encontrará más mejor en el largo plazo.

Ruby es un lenguaje de programación orientado a objetos y proporciona herramientas muy poderosas para su uso. Lo recomiendo la lectura de un libro como "The Ruby Lenguaje de programación" o "The Ruby Way" para obtener una visión adecuada de la potencia del lenguaje.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top