Scala - 创建所有可能字符串的集合减去单词中的一个剪切字母

dan*_*nik 2 collections scala

我还在学习scala.如果我有一个字

val word = "abcd"
Run Code Online (Sandbox Code Playgroud)

我想创造

Map("bcd","acd","abd","abc")
Run Code Online (Sandbox Code Playgroud)

到目前为止我尝试过:

  println(word.map(word.split(_).foldLeft("")(_+_)))
Run Code Online (Sandbox Code Playgroud)

但如果我在单词中有重复的字符,它就会失败.

请帮忙.

Tra*_*own 8

它不一定是最有效的方法,但你可以用initstails方法很干净地完成这个,而不需要处理索引,这些索引可能是"功能较少":

scala> val word = "abcd"
word: String = abcd

scala> (word.inits.toList.tail.reverse zip word.tails.toList.tail).map {
     |   case (x, y) => x + y
     | }
res0: List[String] = List(bcd, acd, abd, abc)
Run Code Online (Sandbox Code Playgroud)

它将按预期工作,具有重复项.

要了解它的工作原理,请考虑以下事项:

scala> word.inits foreach println
abcd
abc
ab
a


scala> word.tails foreach println
abcd
bcd
cd
d
Run Code Online (Sandbox Code Playgroud)

从那里开始,只需将两者结合在一起即可得到理想的结果.


下面是使用了更先进的解决方案Scalaz库的实现的拉链,它提供了一个非常干净的方式来解决这个问题:

import scalaz._, Scalaz._

"abcd".toList.toZipper.map(
  _.cobind(z => (z.lefts.reverse ++ z.rights).mkString).toList
)
Run Code Online (Sandbox Code Playgroud)

这将返回Some(List(bcd, acd, abd, abc)),其中可选的包装器表示空拉链没有意义.实际上,您可能希望以相同的方式对解决方案进行建模(如果您打算使其更通用),因为"留出一个空字符串"也没有意义.

如果你不在乎,只想让空字符串产生一个空列表,你可以getOrElse Nil在这里附加.