Scala:使用最后一个非空值填充List中的间隙

时间:2016-01-27 12:29:15

标签: scala collections

我有一个列表:

val arr = Array("a", "", "", "b", "c", "")

我正在寻找一种创造方式:

Array("a", "a", "a", "b", "c", "c")

3 个答案:

答案 0 :(得分:1)

您可以尝试使用折叠,简单(理解)方法是左折:

(Array.empty[String] /: arr) {
    case (prev, "") => prev :+ prev.lastOption.getOrElse("");
    case (prev, l) => prev :+ l
}

> res01: Array[String] = Array(a, a, a, b, c, c)

根据源元素是否为空字符串,通过附加arr元素或结果列表的最后一个元素来构建前一个新数组。

你也可以把它写成:

(Array.empty[String] /: arr) {
    case (Array(), l) => Array(l)
    case (prev, "") => prev :+ prev.last;
    case (prev, l) => prev :+ l
}

可以使用列表和前置来优化它:

{(List.empty[String] /: arr) {
    case (Nil, l) => l::Nil
    case (h::tail, "") => h::h::tail;
    case (prev, l) => l::prev
} reverse } toArray

如果您不喜欢左侧折叠和折叠右侧方法的符号版本。它附带了文本标识符:

arr.foldLeft(Array.empty[String]) {
    case (prev, "") => prev :+ prev.lastOption.getOrElse("");
    case (prev, l) => prev :+ l
}

arr.foldLeft(List.empty[String]) {
    case (Nil, l) => l::Nil
    case (h::tail, "") => h::h::tail;
    case (prev, l) => l::prev
}.reverse toArray

它采用完全相同的方法和实现,但名称不同。

答案 1 :(得分:0)

不确定这是否是一种优雅的方式,但找到了一个解决方案:

var temp = "" 
arr.map{ case "" => { temp }; case v => {temp=v; v } }

答案 2 :(得分:0)

我认为Mohitt的答案是一个明确的解决方案......但是PabloFranciscoPérezHidalgo对于有副作用是正确的

也许我们可以在函数中包含变量,以避免其他开发人员更改temp变量

(x: Array[String]) => { var last = ""; x.map { v => if (v != "") last = v; last } }

这样使用:

val fillEmpty = (x: Array[String]) => { var last = ""; x.map { v => if (v != "") last = v; last } }
fillEmpty(arr)