ley*_*ren 0 sorting functional-programming scala pattern-matching case-class
给定一些扩展共同特征的案例类,我希望能够根据它们的类型定义一个排序(实际上不一定,目标是以这种方式对它们进行排序)。例如:
sealed trait Element
case class A(x: Int) extends Element
case class B(x: Int) extends Element
case class C(x: Int) extends Element
case class D(x: Int) extends Element
case class E(x: Int) extends Element
case class F(x: Int) extends Element
val elements: List[Element] = List(
A(5), F(3), E(1), C(19), A(3), F(1)
)
Run Code Online (Sandbox Code Playgroud)
排序为F -> A -> all other cases,因此结果列表为List(F(3), F(1), A(5), A(3), E(1), C(19))。相同类型元素之间的顺序无关紧要。
我想出了多种不同的解决方案,但它们看起来都很复杂,我只是觉得我错过了一些明显的方法来实现这一点。这就是我使用排序实现它的方式:
val sorted = elements.sorted{(a: Element, b: Element) => (a, b) match {
case (_: F, _: F) => 0
case (_: F, _ ) => -1
case (_ , _: F) => 1
case (_: A, _: A) => 0
case (_: A, _ ) => -1
case (_ , _: A) => 1
case _ => 0
}
}
Run Code Online (Sandbox Code Playgroud)
然而,这显然会可怕地扩展,并且不好看..
只需定义一个implicit Orderingfor Element:
object Element {
implicit val ord: Ordering[Element] = Ordering.by {
case _: F => 0
case _: A => 1
case _ => 2
}
}
Run Code Online (Sandbox Code Playgroud)
然后elements.sorted会给你你想要的答案。