¿Cómo puedo ordenar por varias condiciones con los diferentes órdenes?

StackOverflow https://stackoverflow.com/questions/73032

  •  09-06-2019
  •  | 
  •  

Pregunta

Realmente me gustaría manejar esto sin monkey patching pero no he sido capaz de encontrar otra opción todavía.

Tengo un array (en Ruby) que necesito para ordenar por varias condiciones.Sé cómo usar el método de ordenación, y yo he usado el truco en la clasificación con una gran variedad de opciones para ordenar por varias condiciones.Sin embargo, en este caso me falta la primera condición para ordenar en forma ascendente y el segundo para ordenar descendente.Por ejemplo:

ordered_list = [[1, 2], [1, 1], [2, 1]]

Alguna sugerencia?

Editar:Acabo de darme cuenta de que debo mencionar que yo no puedo comparar fácilmente la primera y la segunda los valores (de hecho estoy trabajando con los atributos de los objetos aquí).Así que para un simple ejemplo es más como:

ordered_list = [[1, "b"], [1, "a"], [2, "a"]]
¿Fue útil?

Solución

Cómo acerca de:


ordered_list = [[1, "b"], [1, "a"], [2, "a"]]
ordered_list.sort! do |a,b|
  [a[0],b[1]] <=> [b[0], a[1]]
end

Otros consejos

Yo estaba teniendo una pesadilla de un tiempo tratando de averiguar cómo revertir tipo de un atributo específico, pero normalmente ordenar los otros dos.Sólo una nota acerca de la clasificación para aquellos que vienen después de esto y están confundidos por el |a,b| bloque de sintaxis.Usted puede utilizar el {|a,b| a.blah <=> b.blah} estilo de bloque con sort_by! o sort_by.Debe ser utilizado con sort! o sort.También, como se indicó anteriormente por los otros carteles de intercambio a y b a través del operador de comparación <=> para invertir el orden.Como este:

Para ordenar por bla, y craw normalmente, pero, por bleu en orden inverso hacer esto:

something.sort!{|a,b| [a.blah, b.bleu, a.craw] <=> [b.blah, a.bleu, b.craw]}

También es posible el uso de la - firmar con sort_by o sort_by! para hacer un inversa de números (hasta donde yo soy consciente de que sólo funciona en los números de modo que no lo intente con las cuerdas, como se acaba de errores y mata a la página).

Asumir a.craw es un número entero.Por ejemplo:

something.sort_by!{|a| [a.blah, -a.craw, a.bleu]}

Tuve este mismo problema básico, y resuelto por la adición de este:

class Inverter
  attr_reader :o

  def initialize(o)
    @o = o
  end

  def <=>(other)
    if @o.is && other.o.is
      -(@o <=> other.o)
    else
      @o <=> other.o
    end
  end
end

Este es un contenedor que simplemente invierte la <=> la función, que permite hacer cosas como esta:

your_objects.sort_by {|y| [y.prop1,Inverter.new(y.prop2)]}

Enumerable#multisort es una solución genérica que puede ser aplicado a las matrices de cualquier tamaño, no sólo a aquellos con 2 elementos.Los argumentos son valores booleanos que indican si un campo específico se deben ordenar de forma ascendente o descendente (de uso a continuación):

items = [
  [3, "Britney"],
  [1, "Corin"],
  [2, "Cody"],
  [5, "Adam"],
  [1, "Sally"],
  [2, "Zack"],
  [5, "Betty"]
]

module Enumerable
  def multisort(*args)
    sort do |a, b|
      i, res = -1, 0
      res = a[i] <=> b[i] until !res.zero? or (i+=1) == a.size
      args[i] == false ? -res : res
    end
  end
end

items.multisort(true, false)
# => [[1, "Sally"], [1, "Corin"], [2, "Zack"], [2, "Cody"], [3, "Britney"], [5, "Betty"], [5, "Adam"]]
items.multisort(false, true)
# => [[5, "Adam"], [5, "Betty"], [3, "Britney"], [2, "Cody"], [2, "Zack"], [1, "Corin"], [1, "Sally"]]

He estado usando Glenn receta durante bastante tiempo ahora.Cansado de copiar el código de un proyecto a otro, una y otra vez, me he decidido a hacer una joya:

http://github.com/dadooda/invert

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