代码之家  ›  专栏  ›  技术社区  ›  Basilevs

如何将scala.util.Sorting.quickSort()用于任意类型?

  •  0
  • Basilevs  · 技术社区  · 14 年前

    我现在用的是下面这种难看的方法:

    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被设计成具有有序视图而不是通常的comparator参数?

    3 回复  |  直到 14 年前
        1
  •  2
  •   Daniel C. Sobral    14 年前

    好吧,我不确定你到底对现在的工作有什么不满,但也许你所要找的就是这个?

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

    另一方面,如果问题是元组 Ordered 你想要一个 排序,这就是为什么它在Scala 2.8上改变了。

    *编辑*

    哎哟!抱歉,我现在才意识到你说你更喜欢Scala 2.7解决方案。我很快就修改了这个答案,把2.7的解决方案放在上面。接下来是一个2.8的解决方案。

    Ordering ,不是 命令 ,这是上下文绑定,而不是视图绑定。你可以用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)
    

    data.sortBy((_: AccResult)._2)
    
        2
  •  2
  •   Mia Clarke    14 年前

    扩大你的类型 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)
    
        3
  •  2
  •   Collin    14 年前

    我倾向于使用非隐式的论点,除非它被用在很多地方。

    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类型,其中tuple的第二个成员的类型在作用域中有一个视图,该视图将其转换为可比较的。

    推荐文章