0

I cannot get the Point class to search for the x coordinate maximum with one reduce operation (the following I use map then 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 _ )

This will return

res22: Double = 5.0

How to use a single reduce operation to get the max of x out? I tried the following, but didn't get what I expect.

pts.reduce( _.x max _.x )
<console>:11: error: type mismatch;
 found   : Double
 required: Point
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
Carson Pun
  • 1,742
  • 2
  • 13
  • 20

3 Answers3

3

All these are over-complicated. Use the standard library function that does precisely what is needed here:

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

Or, if the example is just a toy one and the real use case is more complex, you can use aggregate

pts.aggregate(Double.MinValue)( _ max _.x , _ max _) 
The Archetypal Paul
  • 41,321
  • 20
  • 104
  • 134
2

You can either use foldLeft to get to a double:

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

Or you can use reduce to keep passing a Point around and pull its x out afterwards:

pts.reduce((a, b) => if (a.x > b.x) a else b).x
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
  • Thanks it works. May you elaborate how `pts.foldLeft(Double.MinValue)(_ max _.x)` this work? Reading the code, the `MinValue` is counterintuitive as we are trying to take the max. – Carson Pun Sep 11 '15 at 20:52
  • We want the smallest value possible to "seed" our reduce (`fold` is a `reduce` but with a default in case the collection is empty). We start with the smallest entry possible and then take the max of the smallest value possible and our first `Point.x` entry. Then we compare the max of that comparison with our next `Point.x` entry. If we started with a larger value we might wind up with garbage data. (For example, if we started out with 0 and all of our points were `-x` our "max" would be 0, not the smallest negative number in the list.) See also: http://stackoverflow.com/q/17408880/135978 – Sean Vieira Sep 11 '15 at 21:38
1

Using reduce and max

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

Other approaches to find the maximum in a List[Point] includes

pts.map(_.x).max
elm
  • 20,117
  • 14
  • 67
  • 113