2

Ok so I thought this would be a snap, trying to practice Scala's collection operators and my example is a list of points.

The class can calculate and return the distance to another point (as double).

However, fold left doesn't seem to be the right solution - considering elements e1, e2, e3.. I need a moving window to calculate, I need the last element looked at to carry forward in the function - not just the sum

Sum {
  e1.dist(e2)
  e2.dist(e3)
  etc
} 

Reading the API I noticed a function called "sliding", perhaps that's the correct solution in conjunction with another operator. I know how to do this with loops of course, but trying to learn the scala way.

Thanks

import scala.math._

case class Point(x:Int, y:Int) {
  def dist(p:Point) = sqrt( (p.x-x)^2+(p.y-y)^2 )

}

object Point {

  //Unsure how to define this?
  def dist(l:Seq[Point]) =l.foldLeft(0.0)((sum:Double,p:Point)=>)

}
Kim Stebel
  • 41,826
  • 12
  • 125
  • 142
LaloInDublin
  • 5,379
  • 4
  • 22
  • 26

2 Answers2

4

I'm not quite sure what you want to do, but assuming you want the sum of the distances:

l.zip(l.tail).map { case (x,y) => x.dist(y) }.sum

Or with sliding:

l.sliding(2).map { 
  case List(fst,snd) => fst.dist(snd)
  case _ => 0
}.sum
Kim Stebel
  • 41,826
  • 12
  • 125
  • 142
3

If you want to do it as a fold, you can, but you need the accumulator to keep both the total and the previous element:

l.foldLeft(l.head, 0.0){ 
  case ((prev, sum), p) => (p, sum + p.dist(prev)) 
}._2

You finish with a tuple consiting of the last element and sum, so use ._2 to get the sum part.

btw, ^ on Int is bitwise logical XOR, not power. Use math.pow.

The smartest way is probably using zipped, which is a kind of iterator so you don't traverse the list more than once as you would using zip:

(l, l.tail).zipped.map( _ dist _ ).sum
Luigi Plinge
  • 50,650
  • 20
  • 113
  • 180
  • Thanks for catching my ^ error, I had thought perhaps this was to match the concept of functions. Can you please explain further what "zipped" is - it seems "zip" also works, I can't find much detail on it in the Seq API or how it differs from zip. – LaloInDublin Nov 01 '12 at 06:09
  • It's a method on Tuple2. See http://stackoverflow.com/q/7068031/770361 and linked answers or post another question! – Luigi Plinge Nov 01 '12 at 12:59