我有一个数组如:
val array = Array("Hello", "```", "blabla", "anything", "filler", "```", "another filler")
filter
方法仅适用于数组的每个元素或Seq
array.filter(s => !s.startsWith("```"))
> Array(Hello, blabla, anything, filler, another filler)
我想删除分隔符"```"
之间的任何内容。最终结果将是
Array("Hello", "another filler")
问题类似于Bracket coding task solved by a Stack。 你怎么能在纯FP中完成这个?
另外
分隔符"```"
分隔了2个部分。
注意:分隔符不相等,但以"```"
开头。有一个"```scala"
val input = Array("Hello", "```", "blabla1", "```", "blabla2", "```scala","blabla3", "filler", "```", "blabla4")
filteredOutput = Array("Hello", "blabla2", "blabla4")
PS:也许你想通了,该解决方案会从降价文件中过滤出代码注释。
答案 0 :(得分:2)
这应符合您的更新要求。
def condense(ss: Seq[String], delimiter: String): Seq[String] = {
val start = ss.indexWhere(_.startsWith(delimiter))
val stop = ss.indexWhere(_.startsWith(delimiter), start + 1)
if (stop < 0) ss
else condense(ss.patch(start, Seq(), stop-start+1), delimiter)
}
condense(input, "```") // res0: Array[String] = Array(Hello, blabla2, blabla4)
答案 1 :(得分:1)
我不确定这是否是最好的方式,但我提出的一种方法是折叠它:
val (filteredOutput: Array[String], _) =
input.foldLeft((Array[String](), true)) {
case ((output: Array[String], include: Boolean), sep) if sep.startsWith("```") => (output, !include)
case ((output: Array[String], true), next: String) => (output :+ next, true)
case ((output: Array[String], false), _) => (output, false)
}
这是一个更新版本,应该处理有关奇数个分隔符的更新要求:
val filteredOutput = {
val (workingOutput: Array[String], _, discard: List[String]) =
input.foldLeft((Array[String](), true, List[String]())) {
case ((output: Array[String], include: Boolean, _), sep) if sep.startsWith("```") =>
(output, !include, if (include) List(sep) else Nil)
case ((output: Array[String], true, _), next: String) =>
(output :+ next, true, Nil)
case ((output: Array[String], false, discard: List[String]), next: String) =>
(output, false, next :: discard)
}
workingOutput ++ discard.reverse
}
答案 2 :(得分:1)
另一个版本,避免使用索引:
val input = Array("Hello", "```", "blabla1", "```",
"blabla2", "```scala", "blabla3", "filler", "```", "blabla4")
def condense(xs: Array[String], acc: Array[String] = Array()): Array[String] = {
if (xs.isEmpty) acc
else {
val (before, after) = xs.span(!_.startsWith("```"))
val remaining = after.drop(1).dropWhile(!_.startsWith("```"))
if (remaining.isEmpty) // unclosed commment
acc ++ xs
else condense(remaining.drop(1), acc ++ before)
}
}
condense(input) //> res0: Array[String] = Array(Hello, blabla2, blabla4)