Chciałbym uzyskać wygodną możliwość sortowania, taką jak za pomocą sortBy. Ale na początku zdefiniujmy sobie pewne rzeczy:
case class Dist(val i: Int) extends Ordered[Dist] { override def compare(b:Dist) = i compareTo b.i }
case class C (val a : Int, val b: Dist, val c: Int)
val l = for (i <- 1 to 2 ; j <- 1 to 2; k <- 1 to 2) yield new C(i,Dist(j),k)
Lista wygląda tak:
scala.collection.immutable.IndexedSeq[C] = Vector(C(1,Dist(1),1), C(1,Dist(1),2), C(1,Dist(2),1), C(1,Dist(2),2), C(2,Dist(1),1), C(2,Dist(1),2), C(2,Dist(2),1), C(2,Dist(2),2))
Mogę sobie ją wygodnie posortować
l.sortBy(p=> (p.a,p.b,p.c))
Ale powiedzmy, że chce napisać sobie swoje sortowanie które bedzie działało podobnie zamiast korzystać z Tupli.
Chce je wywoływać mniej więcej tak:
implicit val MyOrdering = new OrderingOwn[C,_]({c => c.a}, {c=>c.b}, { c=> c.c})
l.sorted
To ma działać tak, że przekazuje kilka funkcji które mówią o porządku sortowania.
W ten sposób miałbym wygodne sortowanie do różnych klas. Wystarczyło by stworzyć odpowiedni obiekt typu OrderingOwn
Jest jednak problem, ponieważ nie wiem jak rozwiązać taką rzecz, że przekazywane przeze mnie funkcje zwracają wartości różnych typów. Oto moja klasa OrderingOwn:
class OrderingOwn[T, U <% Ordered[U]](val pola: Function1[T,U]*) extends Ordering[T] {
def compare (a: T, b:T) = {
pola.dropWhile(p => p(a) == p(b)).headOption.map(p => p(a).compare(p(b))) match {
case Some(i) => i
case None => 0
}
}
}
Dodam że gdy chce posortować po tym samym typie (np Intach) to nie ma problemu:
implicit val MyOrdering = new OrderingOwn[C,Int]({c => c.c}, { c=> c.a})
Pytanie jest takie: jak się uniezależnić od jednego typu i zrobić to aby obsługiwało różne (wszystkie implementujące Ordered) ?