Scala如何将元组列表按嵌套列表的元素为键进行分组
Scala元组列表转逆索引Map实现方案
完全可以通过Scala标准库的高阶函数实现,不需要手写for循环,代码非常简洁。
核心实现代码(Scala 2.13+)
// 示例数据定义 val p = List(("a", List("x","y","z")), ("b", List("x")), ("c", List("y","z"))) // 转换逻辑 val q = p .flatMap { case (parentKey, childList) => childList.map(child => (child, parentKey)) } .groupMap(_._1)(_._2)
运行后得到的q就是你需要的结果:Map(x -> List(a,b), y -> List(a,c), z -> List(a,c))
逻辑拆解
- flatMap阶段:把原列表的每个元组拆成多个
(子元素, 父元组首元素)的二元组,最终合并成一个扁平化的二元组列表。示例运行后这个阶段的输出为:List(("x","a"), ("y","a"), ("z","a"), ("x","b"), ("y","c"), ("z","c")) - groupMap阶段:先按二元组的第一个元素(即子元素x/y/z)分组,再提取每个分组内二元组的第二个元素组成列表,一步得到目标Map。
低版本兼容写法(Scala 2.12及更早)
如果你的Scala版本低于2.13,没有groupMap方法,可以用groupBy加mapValues实现:
val q = p .flatMap { case (parentKey, childList) => childList.map(child => (child, parentKey)) } .groupBy(_._1) .view .mapValues(_.map(_._2)) .toMap
等价for推导式写法
如果觉得flatMap的写法不好理解,也可以用for推导式实现,本质是高阶函数的语法糖,和上面的实现逻辑完全一致:
val q = (for { (parentKey, childList) <- p child <- childList } yield (child, parentKey)).groupMap(_._1)(_._2)
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

