Python简单小案例:为简单的案例类定义 Ordering的简单惯用方法

关于Python简单小案例的问题,在ordering scala中经常遇到, 我有一个简单的 scala 案例类实例列表,我想使用list.sorted以可预测的词典顺序打印它们,但收到“没有为...定义隐式排序”。

我有一个简单的 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)
170

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

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的任何类的范围内。Tuples 的隐式Orderings 的存在使TupleN[...]Ordered[TupleN[...]]的所有元素都

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

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 subcl 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的实例进行操作,因此在大多数情况下,直接提供排序可以消除隐式转换。

51
object A {
  implicit val ord = Ordering.by(unapply)
}

这样做的好处是,每当 A 更改时,它都会自动更新。但是,A 的字段需要按照排序使用它们的顺序放置。

29

总结一下,有三种方法可以做到这一点:

对于一次性排序,请使用.sortBy 方法,如 @ Shadowlands 所示

如 @ Keith 所说,用于重用具有 Ordered 特征的排序扩展案例类。

定义自定义排序。此解决方案的好处是您可以重用排序,并有多种方式对同一类的实例进行排序:

case class A(tag:String, load:Int)
object A {
  val lexicographicalOrdering = Ordering.by { foo: A => 
    foo.tag 
  }
  val loadOrdering = Ordering.by { foo: A => 
    foo.load 
  }
}
implicit val ord = A.lexicographicalOrdering 
val l = List(A("words",1), A("article",2), A("lines",3)).sorted
// List(A(article,2), A(lines,3), A(words,1))
// now in some other scope
implicit val ord = A.loadOrdering
val l = List(A("words",1), A("article",2), A("lines",3)).sorted
// List(A(words,1), A(article,2), A(lines,3))

回答您的问题Scala 中是否包含任何标准函数,可以像 List((2,1),(1,2)).sorted

有一组predefined orderings,例如对于 String,元组高达 9 arity 等等。

案例类不存在这样的事情,因为它不容易滚下来,因为字段名称不知道先验(至少没有宏魔术),你不能以其他方式访问案例类字段通过名称 / 使用产品迭代器。

8

伴随对象的unapply方法提供了从您的 case 类到Option[Tuple]的转换,其中Tuple是对应于 case 类的第一个参数列表的元组。

case class Person(name : String, age : Int, email : String)
def sortPeople(people : List[Person]) = 
    people.sortBy(Person.unapply)

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(685)
Python与运维:二维一维FFT与clFFT
上一篇
Linux mint:Apache不在linuxmint中启动
下一篇

相关推荐

  • python 词性标注:Exploring the Benefits of Python Nouns

    Python 词性标注是指对 Python 语言中的文本进行词性标注的过程。词性标注是将文本中的每个单词分配一个词性(或标记)的过程,以便于计算机能够理解文本的意思。…

    2024-03-17 12:54:47
    0 36 54
  • python浅拷贝和深拷贝区别、原理与实现

    示例示例Python中的浅拷贝和深拷贝是指在复制对象时,复制的结果和原来的对象之间的关系。浅拷贝:浅拷贝只复制一层,也就是说,它只复制最外围的对象,而不复制它包含的对象。如果最外围的对象中包含其他对象,那么这些对象将不会被复制,而是使用原来的对象。…

    2023-05-30 14:25:17
    0 85 16
  • python程序员待遇:Python程序员薪酬最高,收入惊人!

    Python程序员的待遇取决于他们的技能水平和工作经验。一般来说,Python程序员的薪资水平较高,尤其是对于那些有丰富工作经验的Python程序员而言,他们的薪资水平更高。此外,Python程序员还可以获得许多其他福利,包括住房补贴、交通补贴、带薪休假等。…

    2023-06-22 01:21:15
    0 12 30
  • python文本情感分析(含代码示例)

    Python文本情感分析是一种使用自然语言处理技术来分析文本中的情感倾向的过程。它可以帮助我们了解用户对特定主题的看法,从而改善产品和服务。…

    2023-04-23 00:28:07
    0 41 61
  • python字符串拼接数字从零开始

    实例实例Python字符串拼接数字,可以使用format()函数或者%运算符来实现。代码实例:…

    2023-08-20 08:25:28
    0 77 10
  • python中import re:如何使用Python中的re模块进行正则表达式匹配

    import re 是Python中正则表达式模块,可以用来处理字符串。它提供了一系列的函数,可以用来查找、替换和分割字符串,以及检查字符串是否符合特定的格式。…

    2023-05-02 10:25:33
    0 30 39
  • python安装pygame失败:解决python安装pygame失败的方法

    Python安装pygame失败的原因可能有很多,下面是一些常见的原因:安装环境不兼容:pygame只支持python2.7以上版本,而您可能安装的是python3.x或更低版本。…

    2023-04-15 03:55:19
    0 63 80
  • python是面向Python的优势

    Python是一种面向对象的编程语言,它提供了一种简单而强大的方法来创建可重用的代码。它使用类和对象来实现面向对象编程,允许程序员将代码封装在类中,以便在不同的程序中重复使用。…

    2023-05-02 04:34:35
    0 25 50

发表评论

登录 后才能评论

评论列表(73条)