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

Scala实现:对元组列表中相同日期的数值求和

Scala按日期聚合总花费的优雅实现

嗨,这个需求用Scala的函数式集合操作可以非常优雅地解决,完全不用命令式的循环逻辑~

核心思路

我们需要完成两个关键步骤:

  • 按日期对原始列表中的元素进行分组
  • 对每个日期分组内的金额进行求和,最终转换为目标格式的列表

方案一:使用groupBy + 映射求和(兼容所有Scala版本)

这是最通用的实现方式,不管你用哪个Scala版本都能跑:

def sumByDate(bought: List[(String, Double, String)]): List[(String, Double)] = {
  bought
    // 第一步:按日期分组,得到键为日期、值为对应元素列表的Map
    .groupBy(item => item._3)
    // 第二步:遍历每个分组,计算总金额并转换为目标元组
    .map { case (date, itemsInDate) =>
      val totalAmount = itemsInDate.map(_._2).sum
      (date, totalAmount)
    }
    // 最后把Map转换为List
    .toList
}

方案二:使用groupMapReduce(Scala 2.13+ 推荐)

如果你的项目用的是Scala 2.13及以上版本,推荐用groupMapReduce,它把分组、映射、聚合三个步骤合并成一个操作,代码更简洁高效:

def sumByDate(bought: List[(String, Double, String)]): List[(String, Double)] = {
  bought
    // 三个参数分别是:分组键(日期)、元素映射(取金额)、聚合逻辑(求和)
    .groupMapReduce(_._3)(_._2)(_ + _)
    .toList
}

关于你原来的思路

你之前先提取日期集合再用for推导式的思路其实也能实现,但效率会低一些(每个日期都要重新遍历整个列表过滤求和),如果要改进的话可以写成这样,但还是不如上面的函数式方法优雅:

val dates = bought.map(_._3).toSet.toList
val result = for {
  date <- dates
  total = bought.filter(_._3 == date).map(_._2).sum
} yield (date, total)

以上两种推荐方案都是Scala惯用的函数式风格,只需要一次遍历就能完成聚合,代码简洁易读~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 20:37:37