【问题标题】:Scala reduce on Point classScala减少Point类
【发布时间】:2015-12-07 11:37:46
【问题描述】:

我无法通过一个reduce 操作让Point 类搜索x 坐标最大值(以下我使用map 然后reduce

case class Point(x : Double, y : Double)
val pts = List(Point(1,3), Point(-3,2), Point(5,3))

pts.map(p => p.x).reduce( _ max _ )

这将返回

res22: Double = 5.0

如何使用单个reduce 操作来获得x 的最大值?我尝试了以下方法,但没有得到我期望的结果。

pts.reduce( _.x max _.x )
<console>:11: error: type mismatch;
 found   : Double
 required: Point

【问题讨论】:

    标签: scala reduce


    【解决方案1】:

    所有这些都过于复杂。使用完全符合此处需要的标准库函数:

     pts.maxBy(_.x).x   //> res0: Double = 5.0
    

    或者,如果示例只是一个玩具并且实际用例更复杂,您可以使用aggregate

    pts.aggregate(Double.MinValue)( _ max _.x , _ max _) 
    

    【讨论】:

      【解决方案2】:

      您可以使用foldLeft 获得双倍:

      pts.foldLeft(Double.MinValue)(_ max _.x)
      

      或者您可以使用reduce 不断传递Point,然后将其x 拉出:

      pts.reduce((a, b) => if (a.x > b.x) a else b).x
      

      【讨论】:

      • 谢谢它的工作。您能否详细说明pts.foldLeft(Double.MinValue)(_ max _.x) 这是如何工作的?阅读代码,MinValue 是违反直觉的,因为我们试图取最大值。
      • 我们希望尽可能的最小值来“播种”我们的 reduce(foldreduce,但如果集合为空,则使用默认值)。我们从可能的最小条目开始,然后取可能的最小值中的最大值和我们的第一个 Point.x 条目。然后我们将该比较的最大值与我们的下一个Point.x 条目进行比较。如果我们从一个更大的值开始,我们可能会得到垃圾数据。 (例如,如果我们从 0 开始并且我们所有的点都是 -x 我们的“最大值”将是 0,而不是列表中最小的负数。)另见:stackoverflow.com/q/17408880/135978
      【解决方案3】:

      使用reducemax

      pts.map(_.x).reduce( (a,v) => a max v)
      

      List[Point] 中找到最大值的其他方法包括

      pts.map(_.x).max
      

      【讨论】:

      • pts.map(_.x).sorted.last O(NlogN) 最后加上一个额外的不必要的 O(N) 是很好的衡量标准。真的不是一个好的选择......
      猜你喜欢
      • 2018-09-14
      • 2016-06-08
      • 2014-08-04
      • 1970-01-01
      • 1970-01-01
      • 2014-05-19
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多