Wie kann ich durch mehrere Bedingungen mit verschiedenen Ordnungen sortieren?

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

  •  09-06-2019
  •  | 
  •  

Frage

Ich möchte wirklich, dies zu handhaben, ohne Affen Patchen, aber ich habe nicht in der Lage noch eine andere Option zu finden.

Ich habe ein Array (in Ruby), dass ich durch mehrere Bedingungen sortieren müssen. Ich weiß, wie die Sortiermethode zu verwenden, und ich habe den Trick auf Sortierung mit einer Reihe von Optionen, die von mehreren Bedingungen sortieren verwendet. Doch in diesem Fall muss ich die erste Bedingung aufsteigend zu sortieren und die zweite absteigend zu sortieren. Zum Beispiel:

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

Irgendwelche Vorschläge?

Edit: Gerade wurde mir klar, sollte erwähnen, dass ich nicht einfach die ersten und zweiten Werte vergleichen können (ich arbeite tatsächlich mit Objektattributen hier). So für ein einfaches Beispiel ist es mehr wie:

ordered_list = [[1, "b"], [1, "a"], [2, "a"]]
War es hilfreich?

Lösung

Wie wäre:


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

Andere Tipps

Ich hatte einen Albtraum einer Zeit, um herauszufinden, wie Art ein bestimmtes Attribut umkehren, aber normalerweise die beiden anderen sortieren. Nur eine Notiz über die für die Sortierung, die entlang danach kommen und werden durch die verwirrt | a, b | Block-Syntax. Sie können nicht den {|a,b| a.blah <=> b.blah} Block-Stil mit sort_by! oder sort_by verwenden. Es muss mit sort! oder sort verwendet werden. wie zuvor auch, angedeutet durch die anderen Plakate tauschen a und b über den Vergleichsoperator <=> die Sortierreihenfolge umzukehren. Wie folgt aus:

von blah und Kropf sortieren normalerweise, aber sortieren nach bleu in umgekehrter Reihenfolge wie folgt vorgehen:

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

Es ist auch möglich, das - Schild mit sort_by oder sort_by! zu verwenden, um eine umgekehrten Sortierung auf Zahlen (so weit zu tun, wie ich weiß es nur auf Zahlen funktioniert so nicht versuchen, es mit Streichern, da es nur Fehler und tötet die Seite).

Angenommen a.craw eine ganze Zahl ist. Zum Beispiel:

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

Ich hatte das gleiche Grundproblem, und löste es dies durch Hinzufügen:

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

Dies ist ein Wrapper, der einfach die <=> Funktion invertiert, die dann Sie solche Dinge zu tun erlaubt:

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

Enumerable#multisort ist eine generische Lösung, die Anordnungen von angewendet werden kann jeder Größe , nicht nur diejenigen mit 2 Artikel. Die Argumente sind booleans, ob ein bestimmtes Feld angeben sollte auf- oder absteigend (usage unten) sortiert werden:

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

Ich habe jetzt Glenn Rezept für eine ganze Weile im Einsatz. Müde des Kopierens Code von Projekt Projekt über und immer wieder, habe ich beschlossen, es ein Juwel zu machen:

http://github.com/dadooda/invert

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top