Scala按类型对案例类进行排序

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)

然而,这显然会可怕地扩展,并且不好看..

Tim*_*Tim 5

只需定义一个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会给你你想要的答案。