Domanda

Mi piacerebbe davvero riuscire a gestire questo senza scimmia-patch ma non sono stato in grado di trovare un'altra opzione di sicurezza.

Ho un array (in Ruby) che ho bisogno di ordinare da più condizioni.So come utilizzare il metodo di ordinamento e ho usato il trucco sull'ordinamento utilizzando una serie di opzioni per ordinare da più condizioni.Tuttavia, in questo caso ho bisogno di la prima condizione per l'ordinamento crescente e la seconda per ordine decrescente.Per esempio:

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

Qualche suggerimento?

Edit:Capito che devo dire che non mi è possibile confrontare facilmente il primo e il secondo valore (in realtà sto lavorando con gli attributi di un oggetto qui).Così, per un semplice esempio è più simile a:

ordered_list = [[1, "b"], [1, "a"], [2, "a"]]
È stato utile?

Soluzione

Come circa:


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

Altri suggerimenti

Ho avuto un incubo di un tempo cercando di capire come inverso di un attributo specifico, ma di solito ordinare altri due.Solo una nota sull'ordinamento per quelli che vengono dopo e sono confuso con il |a,b| sintassi di blocco.Non è possibile utilizzare il {|a,b| a.blah <=> b.blah} bloccare lo stile con sort_by! o sort_by.Esso deve essere utilizzato con sort! o sort.Inoltre, come indicato in precedenza da altri manifesti di swap a e b attraverso l'operatore di confronto <=> per invertire l'ordine.Come questa:

Per ordinare bla e craw normalmente, ma l'ordinamento bleu in ordine inverso fare questo:

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

È anche possibile utilizzare il - segno con sort_by o sort_by! per fare un reverse ordinare i numeri (per quanto io sappia funziona solo su numeri quindi non provare con le stringhe come solo gli errori e uccide la pagina).

Assumere a.craw è un numero intero.Per esempio:

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

Ho avuto questo stesso problema di base, e risolto aggiungendo questo:

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

Questo è un wrapper che semplicemente inverte il <=> la funzione che consente di fare cose come questa:

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

Enumerable#multisort è una soluzione generica che può essere applicato a matrici di qualsiasi dimensione, e non solo quelli con 2 elementi.Gli argomenti sono boolean che indica se un determinato campo deve essere ordinata in ordine crescente o decrescente (uso qui di seguito):

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"]]

Sto usando Glenn ricetta per un bel po ora.Stanco di copiare il codice da progetto a progetto, più e più volte, ho deciso di realizzare un gioiello:

http://github.com/dadooda/invert

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top