Scala中如何遍历含Map的自定义类列表并聚合生成总分映射
解决Scala中按name聚合学生总分的问题
你之前的代码报错是因为groupMapReduce的映射函数返回了List[Option[Map[String, Integer]]]类型,而Scala的List没有+方法,无法直接用该函数合并列表。要实现按name聚合总分,需要先将每个学生的分数列表转换为单个总分值,再进行聚合。
解决方案代码
case class Student(name: String, standard: String, scores: List[Option[Map[String, java.lang.Integer]]]) val studentList = List( Student("John", "First", List(Option(Map("Sub1" -> 10)), Option(Map("Sub2" -> 20)), Option(Map("Sub3" -> 30)))), Student("Jane", "First", List(Option(Map("Sub1" -> 10)), Option(Map("Sub2" -> 20)), Option(Map("Sub3" -> 30)))), Student("Jimmy", "First", List(Option(Map("Sub1" -> 10)), Option(Map("Sub2" -> 20)), Option(Map("Sub3" -> 30)))) ) // 按name分组,计算每个学生的总分并聚合 val totalScoresByName = studentList.groupMapReduce(_.name)( student => student.scores.flatten.flatMap(_.values).sum )(_ + _) // 打印目标格式结果 totalScoresByName.foreach { case (name, total) => println(s"$name -> $total") }
代码逻辑说明
- 映射函数处理:
student => student.scores.flatten.flatMap(_.values).sumflatten:过滤掉分数列表中的None值,得到有效分数Map的列表flatMap(_.values):提取每个Map中的分数值,合并为一个统一的分数列表sum:对所有分数求和,得到单个学生的总分
- 合并函数作用:
(_ + _):如果存在同名学生,会自动将他们的总分相加,满足聚合需求
简化方案(当name唯一时)
如果列表中每个学生的name都是唯一的,也可以直接转换为Map:
val totalScoresByName = studentList.map(student => student.name -> student.scores.flatten.flatMap(_.values).sum ).toMap
内容的提问来源于stack exchange,提问作者Jay Saraf
相关产品推荐
相关产品推荐

