Scala:map+;用过滤器代替折叠式过滤器

Scala:map+;用过滤器代替折叠式过滤器,scala,functional-programming,foldleft,Scala,Functional Programming,Foldleft,在Scala中,是否可以通过映射和过滤器的某种组合来替代foldLeft函数?例如,在这个任务上 输入是一个三元组列表(学生姓名、课程、年级): 然后,应该为每个学生绘制一份课程和成绩表。foldLeft的情况如下: grades.foldLeft(Map[String, List[(String, Double)]]())((acc, e) => acc + (e._1 -> (acc.getOrElse(e._1, List()) ::: List((e._2, e._3))))

在Scala中,是否可以通过映射和过滤器的某种组合来替代foldLeft函数?例如,在这个任务上

输入是一个三元组列表(学生姓名、课程、年级):

然后,应该为每个学生绘制一份课程和成绩表。foldLeft的情况如下:

grades.foldLeft(Map[String, List[(String, Double)]]())((acc, e) => acc + (e._1 -> (acc.getOrElse(e._1, List()) ::: List((e._2, e._3))))).toList
输出:

List[(String, List[(String, Double)])] = List((Hans,List((db,2.3), (prog2,1.7), (prog1,2.0))), (Maria,List((prog1,1.0), (prog2,1.3), (prog3,1.7), (mathe1,1.3))), (Josef,List((prog1,1.3), (db,3.3))))
如何仅使用map和filter函数实现相同的输出? 到目前为止,我有这个,但输出略有不同

grades.map(x => (x._1, List())).distinct.flatMap(x => grades.map(z => if(!x._2.contains(z._2, z._3)) (x._1, x._2 ::: List((z._2, z._3)))))

使用
groupBy
是解决此问题的好方法:

grades
  .groupBy(_._1)
  .mapValues(_.map(t => (t._2, t._3)))

(感谢m4gic从评论中建议的改进到原始版本)

使用
groupBy
是解决此问题的好方法:

grades
  .groupBy(_._1)
  .mapValues(_.map(t => (t._2, t._3)))

(由于m4gic从注释中建议的原始版本改进到了原始版本)

使用case类而不是tuple/triple将使代码更易于阅读并减少错误这似乎是一个编程挑战,而不是真正的帮助请求。请将问题限制为您需要解决的真实问题。谢谢。使用case类而不是tuple/triple将使代码更易于阅读并减少错误。这似乎是编程方面的挑战,而不是真正的帮助请求。请将问题限制为您需要解决的真实问题。谢谢。或者,没有案例:grades.groupBy(._1).mapValues(.map(tpl=>(tpl._2,tpl._3)))谢谢你的建议。挑战是真正限制自己映射和过滤。@LeoWagner您接受的答案使用了
distinct
:为什么
distinct
可以,但是
groupBy
不行?或者,没有案例的话:grades.groupBy(.\u 1).mapValues(.map(tpl=>(tpl.\u 2,tpl.\u 3)),谢谢您的建议。挑战在于真正限制自己映射和过滤。@LeoWagner您接受的答案使用了
distinct
:为什么
distinct
可以,而
groupBy
不行?宁可使用
。收集
也要使用
。收集
grades
  .map({ case (name, _, _) => name })
  .distinct
  .map(name => {
    val scores = grades
      .filter({ case (nameInternal, _, _) => name == nameInternal })
      .map({ case (_, subject, score) => (subject, score) })
    (name, scores)
  })

// res0: List[(String, List[(String, Double)])] = List((Hans,List((db,2.3), (prog2,1.7), (prog1,2.0))), (Maria,List((prog1,1.0), (prog2,1.3), (prog3,1.7), (mathe1,1.3))), (Josef,List((prog1,1.3), (db,3.3))))