使用Scala替换先前非零值的数组中的所有零

时间:2016-01-06 19:37:13

标签: scala functional-programming

我想知道是否有一种简洁的方法用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循环很容易做到这一点;是否有可能采用功能性方法?

3 个答案:

答案 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进行重复调用,这可能会减少到一个。