繁体   English   中英

scala:如何使用Ordering对象对Seq进行排序?

[英]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的一些理性和用法。

另请参阅Scala:什么是TypeTag以及如何使用它?

暂无
暂无

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

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