Scala循环中列表拼接失效:结果为嵌套列表而非单个元素
解决Scala循环中列表拼接得到子列表的问题
看起来你遇到的核心问题是最终的names列表变成了嵌套列表(List[List[String]]),而不是你期望的扁平字符串列表。这大概率是两个原因导致的:
问题根源分析
searchIndex的返回值类型不符:如果这个函数返回的不是List[String],而是List[List[String]](也就是每次调用都返回一个包含子列表的列表),那么你用:::=拼接时,是把整个子列表作为单个元素加到names里,而不是把子列表中的元素逐个展开添加。- 不可变List的
:::=用法误区:Scala的不可变List本身没有:::=方法(这个方法属于可变集合ListBuffer),你用var修饰names时,编译器会做隐式转换,但本质上是执行names = influencers_name ::: names——如果influencers_name是嵌套列表,这就会不断往names里加子列表元素。
解决方案
方案1:扁平化嵌套列表(如果searchIndex确实返回嵌套列表)
在拼接前先把influencers_name扁平化,用.flatten方法将嵌套列表转成扁平的字符串列表:
var names: List[String] = Nil val cluster_id = List("149095311_0", "149095311_1") for (id <- cluster_id) { val influencers_name = searchIndex(s"id : $id", "id", "influencers", searcher) println("In Loop " + influencers_name) names = names ::: influencers_name.flatten // 扁平化后再拼接 } for(n <- names) println("List element -> " + n)
方案2:改用函数式风格(推荐,避免可变变量)
Scala更推荐用不可变集合和函数式操作,这里可以用flatMap直接处理,它会自动帮你扁平化结果:
val cluster_id = List("149095311_0", "149095311_1") val names = cluster_id.flatMap { id => val influencers_name = searchIndex(s"id : $id", "id", "influencers", searcher) println("In Loop " + influencers_name) // 如果searchIndex返回嵌套列表,就加.flatten;如果本来就是List[String],直接返回即可 influencers_name.flatten } // 遍历输出 names.foreach(n => println("List element -> " + n))
额外检查:确认searchIndex的返回值
如果你的预期是searchIndex返回List[String],那最好检查这个函数的实现逻辑,看是不是不小心返回了嵌套列表(比如把单个元素包装成了列表,或者查询结果的结构处理错了)。
内容的提问来源于stack exchange,提问作者Monika
相关产品推荐
相关产品推荐

