Scala 接受匿名比较器吗?

发布于 2024-10-17 02:09:24 字数 1015 浏览 0 评论 0原文

我如何接受一个函数作为参数传递给 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)

How can I accept a function to pass to Vector.sortBy() in scala as an argument?

Currently I have a function like this:

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

However, I would like to pass either "_.x" (sort on x) or "_.y" as an argument to the function, so I can do something like this:

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

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

 }

So I would like to check what the current "comparator" is, and then recurse passing it the comparator for the y coordinate.

I hope this is clear. In Java I would write it as:

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝戈者 2024-10-24 02:09:24

实际上,您想要一个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))

Actually, you want an Ordering. Like this:

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!")
   }
 }

The sortBy method just creates an Ordering for you. sortBy(_.x) is equivalent to sorted(Ordering.by(_.x)).

帅气尐潴 2024-10-24 02:09:24

如果您检查文档,您会发现 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)

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

If you check the docs, you see that sortBy takes one argument: f: A => B. Looks like a generic function that takes A as an argument and produces a B. So, let's give that a try:

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

which defines the two functions that we want. Now we can call

data.sortBy(orderer)

and test

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

(though I would recommend passing in both comparators as arguments rather than searching for specific constants).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文