繁体   English   中英

为什么 Scala 列表没有排序?

[英]Why don't Scala Lists have an Ordering?

为什么在 Scala 中没有隐式的列表排序是有原因的?

val lists = List(List(2, 3, 1), List(2, 1, 3))
lists.sorted

error: could not find implicit value for parameter ord: Ordering[List[Int]]

编辑

是的,我的问题是为什么没有已经隐含在范围内的内置排序。 对我来说,很明显第二个列表应该“小于”第一个列表,因为 0 处的项目是相等的,而第二个列表中较低的项目为 1。我想知道当列表有两种不同的大小。

我认为这是一个疏忽。 字典顺序在 Seqs 上确实有意义。 我们应该将它添加到标准库中。

顺便说一句,甚至在我解决这个问题之前,你也可以通过其他方式来做到这一点:

scala> List[Iterable[Int]](List(2, 3, 1), List(2, 1, 3)).sorted
res0: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))

scala> List(List(2, 3, 1), List(2, 1, 3)).sorted(Ordering[Iterable[Int]])
res1: List[List[Int]] = List(List(2, 1, 3), List(2, 3, 1))

但现在它像您希望的那样工作。

编辑:由于必需的隐式存在粗略的分歧问题,我将其移出默认范围。 具有像这样跨越边界的隐式转换:

implicit def SeqDerived[CC[X] <: collection.Seq[X], T](implicit ord: Ordering[T]): Ordering[CC[T]]

...是潜在的问题解决方案。 它将在 2.9 中可用,但您必须按以下方式导入它。

scala> val lists = List(List(2, 3, 1), List(2, 1, 3))
lists: List[List[Int]] = List(List(2, 3, 1), List(2, 1, 3))

scala> lists.sorted
<console>:9: error: could not find implicit value for parameter ord: Ordering[List[Int]]
       lists.sorted
             ^

scala> import Ordering.Implicits._
import Ordering.Implicits._

scala> lists.sorted
res1: List[List[Int]] = List(List(2, 1, 3), List(2, 3, 1))

您拥有的是列表列表,而不是整数列表。 您缺少的是确定列表是否 <= 另一个列表的标准。

错误消息就是这样说的:我找不到将一个列表与另一个列表进行比较的方法,您应该明确提供一个。

如果您的问题是“为什么 list 没有内置的与其他列表进行比较的方法”,那么,这就是它的方式。

List[Int] 类唯一真正合理的总顺序是字典顺序(即,比较列表的第一个元素,如果它们相等,则比较第二个,如果秒数相等,则第三个,等等)。 这不是由标准库提供的,可能是因为实际需要它的情况并不多。 创建一个从 List[X] 到 Ordering[List[X]] 的隐式转换将很容易实现,然后您可以在需要的地方简单地导入该转换。

您可以使用 sortWith。 这不会考虑不同大小的列表,因为 zip 会排除差异,但我认为它的作用类似于您所追求的:

lists.sortWith((a,b) => {
  a.zip(b).filterNot(x => x._1 == x._2) match {
    case Nil => true
    case t => t._1 < t._2
  }
})

在较新的 Scala 版本(使用 2.12.5 测试)中,有一个Iterable[A] 的 Ordering 只需将正确的类型归因于您的变量lists

scala> val lists = List(List(2, 3, 1), List(2, 1, 3))
lists: List[List[Int]] = List(List(2, 3, 1), List(2, 1, 3))

scala> (lists: List[Iterable[Int]]).sorted
res0: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))

或者将元素转换为Iterable[]的实例(这是List[]实例的空操作):

scala> lists.map(_.toIterable).sorted
res1: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))

Scala 2.13.3 - 调用sorted方法对我有用:

import scala.math.Ordering.Implicits.seqOrdering
val lists = List(List(2, 3, 1), List(2, 1, 3))
print(lists.sorted)   // prints List(List(2, 1, 3), List(2, 3, 1)) 

sorted方法是 StrictOptimizedSeqOps 特征的成员,:

override def sorted[B >: A](implicit ord: Ordering[B]): C

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM