gpt4 book ai didi

scala - 为简单案例类定义排序的简单惯用方法

转载 作者:行者123 更新时间:2023-12-03 04:46:30 24 4
gpt4 key购买 nike

我有一个简单的 scala 案例类实例列表,我想使用 list.sorted 以可预测的字典顺序打印它们,但收到“没有为...定义隐式排序”。

是否存在为案例类提供字典顺序的隐式?

是否有简单的惯用方法将字典顺序混合到案例类中?

scala> case class A(tag:String, load:Int)
scala> val l = List(A("words",50),A("article",2),A("lines",7))

scala> l.sorted.foreach(println)
<console>:11: error: No implicit Ordering defined for A.
l.sorted.foreach(println)
^

我对“黑客”不满意:

scala> l.map(_.toString).sorted.foreach(println)
A(article,2)
A(lines,7)
A(words,50)

最佳答案

我个人最喜欢的方法是使用为元组提供的隐式排序,因为它清晰、简洁且正确:

case class A(tag: String, load: Int) extends Ordered[A] {
// Required as of Scala 2.11 for reasons unknown - the companion to Ordered
// should already be in implicit scope
import scala.math.Ordered.orderingToOrdered

def compare(that: A): Int = (this.tag, this.load) compare (that.tag, that.load)
}

这有效是因为 companion to Ordered 定义从 Ordering[T] 的隐式转换至Ordered[T]它在任何实现 Ordered 的类的范围内。隐含的存在OrderingTuple s 启用 TupleN[...] 的转换至Ordered[TupleN[...]]提供了隐式Ordering[TN]所有元素均存在 T1, ..., TN元组的,应该始终如此,因为对没有 Ordering 的数据类型进行排序是没有意义的.

元组的隐式排序是任何涉及复合排序键的排序场景的首选:

as.sortBy(a => (a.tag, a.load))

由于这个答案已被证明很受欢迎,我想对其进行扩展,并指出类似于以下内容的解决方案在某些情况下可以被视为企业级™:

case class Employee(id: Int, firstName: String, lastName: String)

object Employee {
// Note that because `Ordering[A]` is not contravariant, the declaration
// must be type-parametrized in the event that you want the implicit
// ordering to apply to subclasses of `Employee`.
implicit def orderingByName[A <: Employee]: Ordering[A] =
Ordering.by(e => (e.lastName, e.firstName))

val orderingById: Ordering[Employee] = Ordering.by(e => e.id)
}

给定es: SeqLike[Employee] , es.sorted()将按名称排序,并且 es.sorted(Employee.orderingById)将按 id 排序。这有一些好处:

  • 这些排序在单个位置定义为可见的代码工件。如果您对许多字段进行复杂排序,这非常有用。
  • scala 库中实现的大多数排序功能都使用 Ordering 的实例进行操作。 ,因此在大多数情况下直接提供排序可以消除隐式转换。

关于scala - 为简单案例类定义排序的简单惯用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19345030/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com