如何按addressId分组case class AddressData并转换为addressGroupedData输出
实现方案
完整可运行代码
object AddressAssignment extends App { // 定义case class AddressData存储入住数据 case class AddressData( customerId: String, addressId: String, fromDate: Int, toDate: Int ) // 输出数据对应的case class(建议遵循Scala命名规范,类名使用大驼峰) case class AddressGroupedData( group: Long, addressId: String, customerId: Seq[String], startDate: Int, endDate: Int ) // 示例源数据,可替换为实际读取文件解析得到的List val sourceData: List[AddressData] = List( AddressData("IND0023", "ADR000", 923, 1024), AddressData("IND0032", "ADR000", 268, 395), AddressData("IND0001", "ADR003", 1710, 1825), AddressData("IND0007", "ADR003", 1720, 1810) ) // 核心处理逻辑 val groupedResult: List[AddressGroupedData] = sourceData .groupBy(_.addressId) // 按addressId完成分组 .toList .map { case (addressId, dataList) => // 聚合当前分组数据:收集所有用户ID、取最小起始日期、最大结束日期 val customerIds = dataList.map(_.customerId) val startDate = dataList.map(_.fromDate).min val endDate = dataList.map(_.toDate).max (addressId, customerIds, startDate, endDate) } .zipWithIndex // 给分组分配从0开始的自增序号 .map { case ((addressId, customerIds, start, end), index) => AddressGroupedData(index, addressId, customerIds, start, end) } // 转换为你要求的元组格式输出 val outputList = groupedResult.map(g => (g.group, g.addressId, g.customerId, g.startDate, g.endDate)) println(outputList) println(s"Total number of groups: ${groupedResult.length}") }
逻辑说明
- 若需要从外部文件读取数据,仅需替换
sourceData的赋值逻辑,将文件内容逐行解析为AddressData实例即可 - 代码默认取同一地址所有入住记录的最小起始日期、最大结束日期作为分组的起止时间,如果你有特殊的时间合并逻辑(比如仅合并连续入住时间段),可以调整map阶段的聚合规则
- 不需要元组格式的话,直接打印
groupedResult即可输出case class结构的结果
内容的提问来源于stack exchange,提问作者codeNoob0101
相关产品推荐
相关产品推荐

