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

Scala中无需循环合并Map条目最优方案咨询(附具体用例)

Scala合并Map条目的最优函数式实现方案

嘿,这个需求我太熟了!咱们不用写循环,完全用Scala的函数式集合操作就能优雅解决,而且效率也很高。先拆解下你的需求:按原Map键的第一个Int值分组,把同ID下case0和case1对应的List取交集,最后将新键统一设为(Int, "nocase")。

具体实现步骤

首先先明确你的原始数据:

val map1 = Map(
  ((1,"case0") -> List(1,2,3)),
  ((2,"case0") -> List(3,4,5)),
  ((1,"case1") -> List(2,4,6)),
  ((2,"case1") -> List(3))
)

1. 按ID分组

先用groupBy把同ID的条目归到一起,这样每个分组里会包含对应case0和case1的两个键值对:

val groupedById = map1.groupBy { case ((id, _), _) => id }

此时groupedById的结构是Map[Int, Map[(Int, String), List[Int]]],比如ID=1的分组里就包含(1,"case0")和(1,"case1")的两个条目。

2. 计算交集并构建结果Map

接下来对每个分组处理,提取两个List的交集,再构造新的键值对。这里有两种写法:

简洁版(假设每个ID都有case0和case1)

直接用reduce对分组内的所有List取交集(因为每个分组正好两个List):

val result = groupedById.map { case (id, entries) =>
  ((id, "nocase") -> entries.values.reduce(_ intersect _))
}.toMap
健壮版(兼容缺失case的情况)

如果担心某些ID可能只存在case0或case1,可以用getOrElse设置默认空List,避免抛出异常:

val safeResult = groupedById.map { case (id, entries) =>
  val case0List = entries.getOrElse((id, "case0"), List.empty[Int])
  val case1List = entries.getOrElse((id, "case1"), List.empty[Int])
  ((id, "nocase") -> (case0List intersect case1List))
}.toMap

验证结果

运行后你会得到完全符合需求的结果:

// result的输出:
Map((1,nocase) -> List(2), (2,nocase) -> List(3))

为什么这是最优方案?

  • 完全采用函数式编程风格,没有显式循环,代码简洁易读
  • 利用Scala集合的内置高阶函数,底层已经做了优化,性能优于手动循环
  • 扩展性强,如果后续需要处理更多case(比如case2),只需要调整交集的计算逻辑(比如改成entries.values.reduce(_ intersect _)自动处理多个List的交集)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:17:03