为什么Scala列表没有订购?

时间:2010-12-20 19:42:41

标签: scala scala-collections

为什么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.我想知道是否可能是因为没有好的答案列表有两种不同的大小。

7 个答案:

答案 0 :(得分:44)

我认为这是一种疏忽。词典排序对Seqs有意义。我们应该将它添加到标准库中。

答案 1 :(得分:7)

顺便说一下,在我修复此问题之前,您可以采用其他方式:

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))

答案 2 :(得分:4)

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

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

如果您的问题是“为什么不列出对其他列表的内置比较方法”,那么就是这样。

答案 3 :(得分:4)

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

答案 4 :(得分:1)

您可以使用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
  }
})

答案 5 :(得分:0)

在较新的Scala版本(已通过2.12.5测试)中,有一个Ordering for Iterable[A]。只需将正确的类型分配给变量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))

答案 6 :(得分:0)

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 trait 的成员,:

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