[英]scala: How to sort Seq with an Ordering object?
来自scala参考: http : //www.scala-lang.org/files/archive/nightly/docs/library/index.html#scala.math.Ordering
case class Person(name:String, age:Int)
val people = Array(Person("bob", 30), Person("ann", 32), Person("carl", 19))
// sort by age
object AgeOrdering extends Ordering[Person] {
def compare(a:Person, b:Person) = a.age compare b.age
}
但是如果我想使用Ordering对象对Seq进行排序:
// Want to sort a Seq, or event and IndexedSeq
val ps = people.asInstanceOf[collection.Seq[Person]]
// Type not enough arguments
// for method stableSort: (implicit evidence$6: scala.reflect.ClassTag[Person],
// implicit evidence$7: scala.math.Ordering[Person])Array[Person]. Unspecified value
// parameter evidence$7.
Sorting.stableSort(ps)(AgeOrdering)
编译器扼流圈。 但是,stableSort API表示需要Seq。 那么为什么上述失败呢?
在Sorting中 , quickSort
实现是就地完成的,有一堆基于索引的移动,只适用于在Array上完成(而Seq根本没有定义索引)。
quickSort[K](a: Array[K] ..): Unit
quickSort方法对输入执行副作用并返回Unit。
但是, stableSort
有两种不同的形式。 采用Seq和采用数组的采样器。
stableSort[K](a: Seq[K] ..): Array[K]
stableSort[K](a: Array[K] ..): Unit
采用数组的形式也返回Unit并修改输入(作为quickSort但确保稳定性),而表单采用Seq返回一个新的Array对象(并且输入序列不被修改)。
错误是因为quickSort
方法具有第二个参数组的签名:( (implicit arg0: math.Ordering[K])
而stableSort
方法具有:( (implicit arg0: ClassTag[K], arg1: math.Ordering[K])
-也就是说,它也需要一个ClassTag [K /人]。
即使指定了顺序,也没有指定(或隐式解析) ClassTag[K]
参数,Scala需要它来创建内部使用(并返回)的Array[Person]
。 由于斯卡拉被Java的类型擦除的限制,该方法没有搞懂什么 K型真的是没有额外的帮助。
我不确定为什么它没有被隐含地解决(因为Scala implicits对我来说仍然是“神奇的”!),但明确地传递它是相当容易的:
val results = Sorting.stableSort(ps)(classTag[Person], AgeOrdering)
在TypeTag和Manifests中讨论了TypeTag / ClassTag的一些理性和用法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.