简体   繁体   中英

type mismatch in scala when using reduce

Can anybody help me understand what's wrong with the code below?

case class Point(x: Double, y: Double)

def centroid(points: IndexedSeq[Point]): Point = {
  val x = points.reduce(_.x + _.x)
  val y = points.reduce(_.y + _.y)
  val len = points.length
  Point(x/len, y/len)
}

I get the error when I run it:

Error:(10, 30) type mismatch;
 found   : Double
 required: A$A145.this.Point
  val x = points.reduce(_.x + _.x)
                            ^

reduce , in this case, takes a function of type (Point, Point) => Point and returns a Point .

One way to calculate the centroid:

case class Point(x: Double, y: Double)

def centroid(points: IndexedSeq[Point]): Point = {
  val x = points.map(_.x).sum
  val y = points.map(_.y).sum
  val len = points.length
  Point(x/len, y/len)
}

If you want to use reduce you need to reduce both x and y in a single pass like this

def centroid(points: IndexedSeq[Point]): Point = {
  val p = points.reduce( (s, p) => Point(s.x + p.x, s.y + p.y) )
  val len = points.length

  Point(p.x/len, p.y/len)
}

If you want to compute x and y independently then use foldLeft rather than reduce like this

def centroid(points: IndexedSeq[Point]): Point = {
  val x = points.foldLeft(0.0)(_ + _.x)
  val y = points.foldLeft(0.0)(_ + _.y)
  val len = points.length

  Point(x/len, y/len)
}

This is perhaps clearer but does process the points twice so it may be marginally less efficient.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM