我有一系列积分。对于除第一点以外的每一点,我想减去前一点:
Array((1,1), (3,1), (4,3))
变为Array((1,1), (2,0), (1,2))
我想出了一种“某种”功能风格:
val trans = for (i <- 0 until points.length - 1)
yield {
(points(i + 1)._1 - points(i)._1, points(i + 1)._2 - points(i)._2)
}
val result = trans ++ points
但我觉得可以做得更好。完成转换后,我将要在result
中添加所有元组。
答案 0 :(得分:4)
通常,你写的for-comprehension是通过zip
完成的:
(xs zip xs.drop(1)).map{ case ((x1,y1), (x2,y2)) => (x2-x1, y2-y1) }
其余的(添加第一个元素)是特殊目的,你可以自己做很多事情。 (您可以将(0,0)
添加到xs.drop(1)
的前面,或将xs.take(1)
添加到结果中。)
另外,请注意,完全可以将整个算法用sum作为单个折叠或递归来编写。
(我假设你在这里没有表现限制。)
答案 1 :(得分:4)
考虑
type Point = (Int,Int)
def sub( p1: Point, p2: Point ) = (p1._1 - p2._1, p1._2 - p2._2)
等等
val points = Array((1,1), (3,1), (4,3))
for ((p1, p2) <- points.zip(points.drop(1)) yield sub(p2,p1)
答案 2 :(得分:0)
sliding
还有Array
方法:
(Iterator(xs(0)) ++
xs.sliding(2)
.map { case Array((x1, y1), (x2, y2)) =>
(x2 - x1, y2 - y1) }).toArray
//> res0: Array[(Int, Int)] = Array((1,1), (2,0), (1,2))
答案 3 :(得分:0)
这是一个执行此操作的功能:
type Pairs = Array[(Int,Int)]
def diff(seq: Pairs): Pairs = Array(seq.head) ++ seq.sliding(2).map{case Array((a1,b1),(a2,b2)) => (a2-a1, b2-b1)}
您可以在REPL中使用它:
scala> diff(Array((1,1), (3,1), (4,3)))
res1: Array[(Int, Int)] = Array((1,1), (2,0), (1,2))
答案 4 :(得分:0)
我的解决方案非常接近榆树。 。 。但我担心他的那个实际上是马车,因为它是A)在屈服之前缺少一个括号而B)正在跳过第一个元素。所以他的结果是Array((2,0), (1,2))
。可悲的是,我不能评论他的解决方案,因为我没有足够的声誉。所以这是我的解决方案:
implicit class PointUtils( val point:(Int, Int) ) extends AnyVal {
def subtract(other:(Int, Int)) = ( point._1 - other._1, point._2 - other._2 )
}
val points = Array((1,1), (3,1), (4,3))
for( (p1, p2) <- points.zip( (0,0) +: points ) ) yield p1.subtract( p2 )
//alternatively
points.zip( (0,0) +: points ).map( t => t._1.subtract(t._2) )
我对隐式课程略有偏好,但很多人会认为榆树def sub(...)
更容易理解。
另请注意,我的版本比elms使用更多内存,因为(0,0) +: points
需要复制points
数组,其中points.drop(1)
没有。当您使用列表时,内存命中会消失。