如何使用任意类型的scala.util.Sorting.quickSort()?

时间:2010-11-06 08:07:22

标签: scala

我需要按第二个元素对一对数组进行排序。如何将我的对的比较器传递给quickSort函数? 我现在正在使用以下丑陋的方法:

type AccResult = (AccUnit, Long) // pair
class Comparator(a:AccResult) extends Ordered[AccResult] {
        def compare(that:AccResult) = lessCompare(a, that)
        def lessCompare(a:AccResult, that:AccResult) = if (a._2 == that._2) 0 else if (a._2 < that._2) -1 else 1
}
scala.util.Sorting.quickSort(data)(d => new Comparator(d))

为什么quickSort设计为具有有序视图而不是通常的比较器参数?

首选Scala 2.7解决方案。

3 个答案:

答案 0 :(得分:2)

让您的类型扩展Ordered,如下所示:

case class Thing(number : Integer, name: String) extends Ordered[Thing] {
  def compare(that: Thing) = name.compare(that.name)
}

然后将它传递给sort,就像这样:

val array = Array(Thing(4, "Doll"), Thing(2, "Monkey"), Thing(7, "Green"))
scala.util.Sorting.quickSort(array)

打印阵列将为您提供:

array.foreach{ e => print(e) }
>> Thing(4,Doll) Thing(7,Green) Thing(2,Monkey)

答案 1 :(得分:2)

好吧,我不确定你对你目前正在做什么感到不满意,但也许你所要找的就是这个?

implicit def toComparator(a: AccResult) = new Comparator(a)
scala.util.Sorting.quickSort(data)

另一方面,如果问题是元组 Ordered并且您想要不同的排序,那么,这就是它改变的原因Scala 2.8。

*编辑*

哎哟!对不起,我现在才意识到你说你更喜欢Scala 2.7解决方案。我很快就编写了这个答案,为上面的2.7提供了解决方案。以下是2.8解决方案。

Scala 2.8需要Ordering,而不是Ordered,这是一个上下文绑定,而不是视图绑定。你可以用2.8编写你的代码:

type AccResult = (AccUnit, Long) // pair 
implicit object AccResultOrdering extends Ordering[AccResult] { 
        def compare(x: AccResult, y: AccResult) = if (x._2 == y._2) 0 else if (x._2 < y._2) -1 else 1 
}

或者只是:

type AccResult = (AccUnit, Long) // pair 
implicit val AccResultOrdering = Ordering by ((_: AccResult)._2)

并使用它:

scala.util.Sorting.quickSort(data)

另一方面,在Scala 2.8中进行排序的常用方法就是调用其中的一种排序方法,例如:

data.sortBy((_: AccResult)._2)

答案 2 :(得分:2)

我倾向于选择非隐式参数,除非它在多个地方使用。

type Pair = (String,Int)
val items : Array[Pair] = Array(("one",1),("three",3),("two",2))
quickSort(items)(new Ordering[Pair] {
  def compare(x: Pair, y: Pair) = {
    x._2 compare y._2
  }
})

编辑:在了解了另一个问题中的视图边界后,我认为这种方法可能更好:

val items : Array[(String,Int)] = Array(("one",1),("three",3),("two",2))

class OrderTupleBySecond[X,Y <% Comparable[Y]] extends Ordering[(X,Y)] {
  def compare(x: (X,Y), y: (X,Y)) = {
    x._2 compareTo y._2
  }
}

util.Sorting.quickSort(items)(new OrderTupleBySecond[String,Int])

通过这种方式,OrderTupleBySecond可用于任何Tuple2类型,其中元组的第二个成员的类型具有范围中的视图,该视图将其转换为Comparable。