我希望此代码返回Seq(List(a,2), List((a,2),(e,1)), List((a,2),(e,1),(t,1)))
,但它会返回一个空的Vector
:
val ws: List[(Char,Int)] = List((a,2), (e,1), (t,1))
def encode(ws: List[(Char,Int)]): Seq[List[(Char,Int)]] =
for {
split <- (1 to ws.length)
wst <- ws.take(split)
wdt <- encode(ws.drop(split))
} yield wst::wdt
为什么返回空Vector
?当我单独尝试语句wst <- ws.take(split)
时,结果为List((a,2))
。
答案 0 :(得分:2)
产生所需输出的快速一行
你真正想要的似乎是:
println(ws.inits.toList.reverse.tail)
// output:
// List(List((a,2)), List((a,2), (e,1)), List((a,2), (e,1), (t,1)))
为什么要清空Vector?
在这种或那种方式中,参数ws
的长度在递归调用期间减少(因为在递归调用encode
之前至少删除了一个元素)。
一旦ws
的长度达到零,ws.take
- 生成器就会变空,因此您的for
- 表达式变为
基本上
(1 to someNumber).flatMap(_ => Nil)
由于Range
在映射/ flatMapping之后产生Vector
,因此您获得一个空Vector()
,然后返回。
长递归解决方案
如果您(无论出于何种原因)坚持使用递归,您可以执行以下操作:
val ws: List[(Char,Int)] = List(('a',2), ('e',1), ('t',1))
def encode(ws: List[(Char,Int)]): Seq[List[(Char,Int)]] =
if (ws.isEmpty) {
Nil
} else {
encode(ws.dropRight(1)) ++ List(ws)
}
println(encode(ws))
// output:
// List(List((a,2)), List((a,2), (e,1)), List((a,2), (e,1), (t,1)))
正确的递归通常应该是这样的:你分别处理Nil
- case和非空列表情况,而不是依赖于用尽迭代的奇怪的flatMap
上。
请注意,此解决方案效率不高,创建辅助方法并反转输入可能会更好。