在Scala中接受匿名比较器?

时间:2011-02-13 02:51:12

标签: java scala

我如何接受一个函数作为参数传递给scala中的Vector.sortBy()?

目前我有这样的功能:

private def buildTree(data: Vector[Data2D]): Node = {
   var sorted: Vector[Data2D] = data.sortBy(_.x)
   // etc...
 }

但是,我想传递“_.x”(在x上排序)或“_.y”作为函数的参数,所以我可以这样做:

private def buildTree(data: Vector[Data2D], comparator): Node = {
   var sorted: Vector[Data2D] = data.sortBy(comparator)
   // etc...

   if(comparator == _.x){
       buildTree(data, _.y)
   }

 }

所以我想查看当前的“比较器”是什么,然后递归传递给y坐标的比较器。

我希望这很清楚。在Java中我会把它写成:

private Node buildTree(List<Data2D> data, Comparator<Data2D> comparator) {
 // Sorted on x or y
 Collections.sort(data, comparator);

 // ... snip ...

 if (comparator instanceof XComparator) {
    // Recurse
    Node subtree = buildTree(data, YComparator.INSTANCE);
    ret.setSubtree(subtree);
 }
 return ret;
}

// Then build tree is called like:
Node root = tree.buildTree(data, XComparator.INSTANCE)

2 个答案:

答案 0 :(得分:3)

实际上,你需要一个Ordering。像这样:

class XOrdering extends Ordering[Data2D] {
    override def compare(x: Data2D, y: Data2D): Int = Ordering.Int(x.x, y.x)
}

class YOrdering extends Ordering[Data2D] {
    override def comapre(x: Data2D, y: Data2D): Int = Ordering.Int(x.y, y.y)
}

private def buildTree(data: Vector[Data2D], ordering: Ordering[Data2D]): Node = {
   var sorted: Vector[Data2D] = data.sorted(ordering)
   // etc...

   ordering match {
     case _: XOrdering => buildTree(data, YOrdering)
     case _: YOrdering => buildTree(data, XOrdering)
     case _ => error("I don't know what that ordering is!")
   }
 }

sortBy方法只为您创建OrderingsortBy(_.x)相当于sorted(Ordering.by(_.x))

答案 1 :(得分:0)

如果您查看文档,则会看到sortBy只接受一个参数:f: A => B。看起来像一个泛型函数,它将A作为参数并生成B。所以,让我们试一试:

val orderX = (d: Data2D) => d.x
val orderY = (d: Data2D) => d.y

定义了我们想要的两个函数。现在我们可以打电话了

data.sortBy(orderer)

并测试

if (orderer==orderX) buildTree(data, orderY)

(虽然我建议将两个比较器作为参数传递,而不是搜索特定的常量)。