使用foldleft或其他算子计算点距离?

时间:2012-10-31 06:48:29

标签: scala collections

好的,所以我认为这会很快,试图练习Scala的集合运算符,我的例子是一个点列表。

该类可以计算并返回到另一个点的距离(为double)。

然而,折叠左边似乎不是正确的解决方案 - 考虑元素e1,e2,e3 ..我需要一个移动的窗口来计算,我需要最后一个元素看待在功能中继续 - 不仅仅是总和

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

读取API我注意到一个名为“滑动”的函数,也许这是与另一个运算符一起使用的正确解决方案。我当然知道如何用循环来做这个,但是试着学习scala方式。

由于

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)=>)

}

2 个答案:

答案 0 :(得分:4)

我不太确定你想做什么,但假设你想要距离之和:

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

或滑动:

l.sliding(2).map { 
  case List(fst,snd) => fst.dist(snd)
  case _ => 0
}.sum

答案 1 :(得分:3)

如果你想把它作为折叠,你可以,但你需要累加器来保持总数和前一个元素:

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

你完成了一个由最后一个元素和总和组成的元组,所以使用._2得到总和部分。

btw,Int上的^是按位逻辑XOR,而不是幂。使用math.pow

最聪明的方法可能是使用zipped,这是一种迭代器,因此您不会像使用zip那样多次遍历列表:

(l, l.tail).zipped.map( _ dist _ ).sum