Scala中如何将元组序列转换为指定结构的另一元组序列
问题解答:反转文档与词频的映射关系
我来帮你搞定这个Scala集合转换的需求!你现在有这样一组代表文档词频的元组序列:
Seq(("abc", Map("x" -> 1, "y" -> 2)), ("xyz", Map("x" -> 2, "y" -> 1)))
想要把它转换成以词为核心的序列,每个词对应不同文档中的出现次数,也就是这样的输出:
Seq(("x", Map("abc" -> 1, "xyz" -> 2)), ("y", Map("abc" -> 2, "xyz" -> 1)))
实现思路与代码
核心思路就是把原来的「文档→词频」结构,拆解后重新聚合成「词→文档词频」结构,用Scala的集合操作就能轻松实现:
val originalSeq = Seq(("abc", Map("x" -> 1, "y" -> 2)), ("xyz", Map("x" -> 2, "y" -> 1))) val result = originalSeq // 先把每个文档的词频拆成(词,(文档,次数))的小条目 .flatMap { case (doc, freqMap) => freqMap.map((word, count) => (word, (doc, count))) } // 按词分组,把同一个词的所有文档次数条目聚在一起 .groupBy(_._1) // 把每个分组里的条目转换成文档到次数的Map,再整理成目标格式 .map { case (word, docCountPairs) => (word, docCountPairs.map(_._2).toMap) } // 把Map转成序列,符合输出要求 .toSeq // 打印结果验证 println(result) // 输出:Seq((x,Map(abc -> 1, xyz -> 2)), (y,Map(abc -> 2, xyz -> 1)))
分步解释
- flatMap 拆解:遍历每个文档,把文档里的每个词和对应的次数,和文档名绑定成新的二元组,这样就把原来的文档维度结构拆成了词维度的一个个小单元。
- groupBy 聚合:以词作为键,把所有包含这个词的(文档,次数)条目归到一起,方便后续统一处理。
- map 转结构:对每个词的分组,把里面的(文档,次数)列表直接转成Map,就得到了每个词在不同文档中的次数映射。
- toSeq 转序列:把最终的Map转换成序列,完全匹配你需要的输出格式。如果需要固定词的顺序(比如和原序列中出现的顺序一致),可以先收集原序列里的词顺序再调整,不过Scala 2.13+里的Map默认保留插入顺序,toSeq后的结果一般和预期一致。
内容的提问来源于stack exchange,提问作者yalkris
相关产品推荐
相关产品推荐

