2010-12-20 72 views
20

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

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

+2

字典序(你描述)可定义为不同大小的名单,但你需要做出选择,以更短的名单是否长于列出大于或较小。这两种方法都可以用来创建数学有效的订单,而较短的<更长的选项可能适合更多的用例,而更短的>更长的选项也可以使用。这可能是为什么在标准库的List中没有提供隐式排序的原因,但我仍然认为缺少一般的有用性是更可能的原因。 – 2010-12-20 20:24:06

回答

42

我认为这是一个疏忽。在Seqs上,词典排序确实有意义。我们应该将其添加到标准库。

+1

谢谢!我看到你提出了一个跟踪器:http:// lampsvn。epfl.ch/trac/scala/ticket/4097 – 2010-12-20 22:42:35

+0

如果元素类型没有'Ordering',那么缺省值是什么?resp不是'Ordered'? – Raphael 2011-03-13 10:23:31

+0

添加到标准库有何进展? – user222202 2012-01-11 08:55:36

4

你有什么是列表的列表,而不是整数列表。你缺少的是确定列表是否为< =另一个列表的标准,或者不是。

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

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

+0

我认为他的问题是为什么没有确定列表是否是另一个列表的隐式标准。 – 2010-12-20 19:46:52

4

List [Int]类唯一真正明智的总体顺序是词典(即比较列表的第一个元素,然后第二个如果相等,第三个如果秒相等,等等)。这不是标准库提供的,可能是因为没有那么多的实际需要的情况。创建一个从List [X]到Ordering [List [X]]的隐式转换就足够简单了,它将实现该转换,然后您可以在需要的任何地方简单地导入该转换。

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 
    } 
}) 
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)) 
相关问题