Scala: Fill the gaps in a List with last non-empty value

耗尽温柔 提交于 2019-12-31 05:11:17

问题


I have a list like:

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

I am looking for a way to create:

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

回答1:


You can try with fold, the easy (to understand) approach is fold left:

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

This builds a new array from the previous by appending arr elements or the resulting list's last depending on whether the source element is the empty string or not.

You can also write it as:

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

It can be optimized by using lists and prepend:

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

In case you don't like the symbolic version of the fold left and fold right methods. Here it comes with its textual identifier:

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

Its exactly the same approach and implementation but with a different name.




回答2:


Not sure if this is an elegant way, but figured out one solution:

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



回答3:


I think Mohitt's answer is a clear solution ... but Pablo Francisco Pérez Hidalgo is right that there are side effects

Maybe we could include the variable inside of a function to avoid changing the temp variable by some other developers

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

to be used like this:

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


来源:https://stackoverflow.com/questions/35037408/scala-fill-the-gaps-in-a-list-with-last-non-empty-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!