Inspiriert von Ben Lings' Antwort schrieb ich meine eigene Version von sort
:
def sort[A : Ordering](coll: Seq[Iterable[A]]) = coll.sorted
, die gleich ist:
def sort[A](coll: Seq[Iterable[A]])(implicit ordering: Ordering[A]) = coll.sorted
Beachten Sie, dass ordering
implizit zu Ordering[Iterable[A]]
umgewandelt.
Beispiele:
scala> def sort[A](coll: Seq[Iterable[A]])(implicit ordering: Ordering[A]) = coll.sorted
sort: [A](coll: Seq[Iterable[A]])(implicit ordering: Ordering[A])Seq[Iterable[A]]
scala> val coll = List(List(1, 3), List(1, 2), List(0), Nil, List(2))
coll: List[List[Int]] = List(List(1, 3), List(1, 2), List(0), List(), List(2))
scala> sort(coll)
res1: Seq[Iterable[Int]] = List(List(), List(0), List(1, 2), List(1, 3), List(2))
Es wurde gefragt, wie Sie Ihre eigene Vergleichsfunktion zu liefern; Es genügt verwenden Ordering.fromLessThan:
scala> sort(coll)(Ordering.fromLessThan(_ > _))
res4: Seq[Iterable[Int]] = List(List(), List(2), List(1, 3), List(1, 2), List(0))
Ordering.by
können Sie Ihren Wert in eine andere Art abzubilden, für die es bereits eine Bestellung Instanz. Da auch Tupel angeordnet sind, kann dies für den lexikografischen Vergleich von Fallklassen nützlich sein.
Um ein Beispiel zu machen, lassen Sie uns einen Wrapper eines Int definieren, gelten Ordering.by(_.v)
, wo _.v
den zugrunde liegenden Wert extrahiert, und zeigen, dass wir das gleiche Ergebnis erhalten:
scala> case class Wrap(v: Int)
defined class Wrap
scala> val coll2 = coll.map(_.map(Wrap(_)))
coll2: List[List[Wrap]] = List(List(Wrap(1), Wrap(3)), List(Wrap(1), Wrap(2)), List(Wrap(0)), List(), List(Wrap(2)))
scala> sort(coll2)(Ordering.by(_.v))
res6: Seq[Iterable[Wrap]] = List(List(), List(Wrap(0)), List(Wrap(1), Wrap(2)), List(Wrap(1), Wrap(3)), List(Wrap(2)))
Schließlich wollen wir das gleiche tun mit mehreren Mitgliedern auf eine Fall-Klasse, die Komparatoren für Tupeln Wiederverwendung:
scala> case class MyPair(a: Int, b: Int)
defined class MyPair
scala> val coll3 = coll.map(_.map(MyPair(_, 0)))
coll3: List[List[MyPair]] = List(List(MyPair(1,0), MyPair(3,0)), List(MyPair(1,0), MyPair(2,0)), List(MyPair(0,0)), List(), List(MyPair(2,0)))
scala> sort(coll3)(Ordering.by(x => (x.a, x.b)))
res7: Seq[Iterable[MyPair]] = List(List(), List(MyPair(0,0)), List(MyPair(1,0), MyPair(2,0)), List(MyPair(1,0), MyPair(3,0)), List(MyPair(2,0)))
persönlich würde ich eher einen rekursiven Algorithmus verwenden, der Schwanz rekursiv für dieses spezielle Problem gemacht werden kann. –
@Daniel, könnten Sie kurz erklären, warum Sie lieber einen rekursiven Algorithmus verwenden würden? –
Listen führen sich relativ leicht zu rekursiven Algorithmen, so dass ich daran denke, Rekursion mit ihnen zu machen. Und in diesem Fall denke ich, dass es sauberer wäre. Dennoch ist es eine Frage von Geschmack und Stil. –