You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala List转Map技术求助:将指定列表转换为目标映射结构

Scala列表转分组映射的实现方法

这其实是Scala里很常见的分组聚合需求,针对你给出的输入和目标输出,我给你几种实用的实现方式:

方法1:groupBy + mapValues + 模式匹配(简洁直观)

这种方法适合你这种每个key对应固定数量元素的场景,代码可读性很高:

val input = List((1,"a1"),(1,"a2"),(1,"a3"),(2,"b1"),(2,"b2"),(2,"b3"))

val result = input.groupBy(_._1).mapValues { groupedList =>
  // 模式匹配提取出三个元素,转成三元组
  val Seq(val1, val2, val3) = groupedList.map(_._2)
  (val1, val2, val3)
}

// 输出结果:Map(1 -> (a1,a2,a3), 2 -> (b1,b2,b3))

原理说明:

  1. groupBy(_._1) 会将列表按元组的第一个元素(也就是数字key)分组,得到一个Map[Int, List[(Int, String)]];
  2. mapValues 遍历每个分组,先通过map(_._2)提取出每个元素的字符串值,再用模式匹配把固定长度的Seq转成你需要的三元组。

注意:如果某个key对应的元素数量不是3个,模式匹配会抛出MatchError,所以这种方法仅适用于元素数量固定的场景。

方法2:foldLeft手动构建(灵活可控)

如果需要更灵活的聚合逻辑,或者担心元素数量可能有变化,可以用foldLeft手动构建映射:

val input = List((1,"a1"),(1,"a2"),(1,"a3"),(2,"b1"),(2,"b2"),(2,"b3"))

val result = input.foldLeft(Map.empty[Int, List[String]]) { (acc, current) =>
  val (key, value) = current
  // 把当前值追加到对应key的列表中,没有则创建新列表
  acc.updated(key, acc.getOrElse(key, Nil) :+ value)
}.mapValues { list =>
  // 把列表转成三元组
  (list(0), list(1), list(2))
}

原理说明:

  1. foldLeft 从空Map开始迭代,每次把当前元素的字符串值添加到对应key的列表里;
  2. 最后再把每个key对应的List转成三元组。这种方法可以方便地修改聚合逻辑(比如过滤值、排序等)。

方法3:Scala 2.13+ 专属的groupMap(高效简洁)

如果你使用的是Scala 2.13及以上版本,可以用新增的groupMap方法,它是groupBy+mapValues的高效组合:

val input = List((1,"a1"),(1,"a2"),(1,"a3"),(2,"b1"),(2,"b2"),(2,"b3"))

val result = input.groupMap(_._1)(_._2).mapValues {
  case Seq(v1, v2, v3) => (v1, v2, v3)
}

原理说明:

groupMap第一个参数是分组的key函数,第二个参数是每个元素要映射的值,一步就能得到Map[Int, List[String]],后续再转成三元组即可,代码更简洁且性能更优。

内容的提问来源于stack exchange,提问作者Bharath Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:53:34