Scala中对List分组并获取每组每日的最小/最大时间戳
解决Scala分组求每日最小/最大时间戳的问题
嘿,这个需求用Scala的集合操作就能轻松实现,我给你一步步拆解:
核心思路
我们需要先把每条记录拆分为「ID、日期、完整时间戳」,然后按ID+日期分组,每组内找出最小和最大的时间戳,最后整理成你想要的输出格式。
完整代码实现
首先要处理时间字符串的解析(如果你的原始数据已经是LocalDateTime类型,可以跳过解析步骤):
import java.time.{LocalDate, LocalDateTime} import java.time.format.DateTimeFormatter // 原始数据(注意时间戳要写成字符串形式,否则编译报错) val data = List( (123, "2018-04-30 10:15:30"), (123, "2018-04-30 11:15:30"), (123, "2018-04-30 12:22:30"), (223, "2018-04-22 10:15:30"), (223, "2018-04-22 13:15:30") ) // 定义日期时间格式化器 val dtFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") val dateFormatter = DateTimeFormatter.ISO_LOCAL_DATE val result = data // 第一步:解析时间戳,提取日期部分 .map { case (id, tsStr) => val fullDt = LocalDateTime.parse(tsStr, dtFormatter) (id, fullDt.toLocalDate, fullDt) } // 第二步:按ID+日期分组 .groupBy { case (id, date, _) => (id, date) } // 第三步:每组内找出最小和最大时间戳 .mapValues { entries => val allDts = entries.map(_._3) (allDts.min, allDts.max) } // 第四步:组装成目标格式的元组 .map { case ((id, date), (minDt, maxDt)) => ( id, date.format(dateFormatter), minDt.format(dtFormatter), maxDt.format(dtFormatter) ) } // 转成List类型 .toList // 打印结果验证 result.foreach(println)
代码解释
- 解析与转换:
map阶段把字符串时间戳解析为LocalDateTime,同时提取出LocalDate(日期部分),得到便于分组的三元组。 - 分组:
groupBy用(id, date)作为分组键,保证同一个ID同一天的记录会被归为一组。 - 求极值:
mapValues里利用LocalDateTime的可比较特性,直接用min和max方法找出组内的最早、最晚时间。 - 格式整理:最后把日期和时间戳重新格式化为字符串,组装成你需要的四元组,再转成List。
运行这段代码后,输出就是你期望的结果:
(123,2018-04-30,2018-04-30 10:15:30,2018-04-30 12:22:30) (223,2018-04-22,2018-04-22 10:15:30,2018-04-22 13:15:30)
内容的提问来源于stack exchange,提问作者jAi
相关产品推荐
相关产品推荐

