Wie kann ich durch mehrere Bedingungen mit verschiedenen Ordnungen sortieren?
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"]]
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: