我还在学习斯卡拉。如果我有一句话
val word = "abcd"
我想创建
Map("bcd","acd","abd","abc")
到目前为止,我尝试过:
println(word.map(word.split(_).foldLeft("")(_+_)))
但如果我在单词中重复了字符,它就会失败。
请帮忙。
我还在学习斯卡拉。如果我有一句话
val word = "abcd"
我想创建
Map("bcd","acd","abd","abc")
到目前为止,我尝试过:
println(word.map(word.split(_).foldLeft("")(_+_)))
但如果我在单词中重复了字符,它就会失败。
请帮忙。
它不一定是最有效的方法,但是您可以使用inits
andtails
方法非常干净地做到这一点,而无需处理可以说“功能较少”的索引:
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)
它将按预期使用重复项。
要了解它是如何工作的,请考虑以下几点:
scala> word.inits foreach println
abcd
abc
ab
a
scala> word.tails foreach println
abcd
bcd
cd
d
从那里只需将两者结合在一起即可获得所需的结果。
下面是一个更高级的解决方案,它使用Scalaz库的 zippers 实现,它提供了一种非常干净的方法来解决这个问题:
import scalaz._, Scalaz._
"abcd".toList.toZipper.map(
_.cobind(z => (z.lefts.reverse ++ z.rights).mkString).toList
)
这将返回Some(List(bcd, acd, abd, abc))
,其中可选的包装器表示空拉链没有意义的事实。实际上,您可能希望以相同的方式对解决方案进行建模(如果您打算使其更通用),因为从空字符串中“省略一个”也没有意义。
如果您不在乎,只想让空字符串生成一个空列表,您可以getOrElse Nil
在此处附加。
scala> def foo(str:String)=(0 until str.length).map(i=>str.substring(0,i)+str.substring(i+1))
foo: (str: String)scala.collection.immutable.IndexedSeq[String]
scala> foo("abcd")
res28: scala.collection.immutable.IndexedSeq[String] = Vector(bcd, acd, abd, abc)
最简单的方法是使用 Scala 在 String 对象上提供的附加方法:
val word = "abcd"
word.combinations(3).toList
或者,如果您想删除重复字符:
word.distinct.combinations(3).toList
评论后更新 如果您想删除重复项,请使用我上面给出的第二个示例。为了您的示例完全准确:
val word = "abca"
word.distinct.combinations(word.distinct.length-1).toList
这返回
res3: List[String] = List(ab, ac, bc)
收藏图书馆是寻找这些东西的最佳场所:
def characterCombinations(word: String) = word
.distinct.combinations(word.distinct.length - 1).toList
characterCombinations("abcdaaaaaa") // outputs List(abc, abd, acd, bcd)
该词可隐式转换为IndexedSeq[Char]
具有常用集合方法的 an ——distinct
删除集合中的重复项,combinations(n)
迭代集合中的n
长度组合,length
为您提供集合的长度,并将toList
转换Iterator[String]
为List[String]
.
这是另一个解决方案:
val word = "abcd"
(0 to 3) map (i => word.split(word(i)).foldLeft("")(_+_))