我想知道是否有一种简洁的方法用Scala中的先前非零值替换数组中的所有零。与此问题类似:pandas replace zeros with previous non zero value
我可以在没有连续零滑动的情况下实现这一点:
scala> Array(1,2,3,0,5,6,7).sliding(2).map {case Array(v1, v2) => if (v2==0) v1 else v2}.toArray
res293: Array[Int] = Array(2, 3, 3, 5, 6, 7)
虽然我必须附加第一个值(在转换为数组之前我会这样做)。
如果有两个连续的零,则上述代码不起作用:
scala> Array(1,2,3,0,0,6,7).sliding(2).map {case Array(v1, v2) => if (v2==0) v1 else v2}.toArray
res294: Array[Int] = Array(2, 3, 3, 0, 6, 7)
所需的结果是Array(2,3,3,3,6,7)
。
使用for循环很容易做到这一点;是否有可能采用功能性方法?
答案 0 :(得分:4)
使用scanLeft
:
Array(1,2,3,0,5,6,7).scanLeft(0)({(left, right) => if (right == 0) then left else right}).tail
答案 1 :(得分:3)
可能有很多方法。您可以使用foldLeft
执行此操作,例如:
Array(1,2,3,0,0,6,7)
.foldLeft(List.empty[Int]){
(acc, v) => if (v != 0) v :: acc else acc.head :: acc
}.reverse.toArray
答案 2 :(得分:2)
递归方法,
def f(xs: Array[Int], nonZ: Int): Array[Int] = {
if (xs.isEmpty) xs
else if (xs.head == 0) nonZ +: f(xs.tail, nonZ)
else xs.head +: f(xs.tail, xs.head)
}
可能会像{<1}}那样被调用
val xs = Array(1,2,3,0,0,6,7)
要注意,没有为以零开头的集合定义问题。另外,这个递归函数会对f(xs, xs.head)
Array(1, 2, 3, 3, 3, 6, 7)
和tail
进行重复调用,这可能会减少到一个。