【问题标题】:Scala: map+filter instead of foldLeftScala:地图+过滤器而不是 foldLeft
【发布时间】:2019-02-10 06:43:30
【问题描述】:

是否可以通过 Scala 中的 map 和 filter 的某种组合来替换 foldLeft 函数?例如在这个任务上。

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

val grades = List(("Hans", "db", 2.3), ("Maria", "prog1", 1.0), ("Maria", "prog2", 1.3), ("Maria", "prog3", 1.7), ("Hans", "prog2", 1.7), ("Josef", "prog1", 1.3), ("Maria", "mathe1", 1.3), ("Josef", "db", 3.3), ("Hans", "prog1", 2.0))

然后,应为每个学生映射他们的课程和成绩列表。使用 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)))))

【问题讨论】:

  • 使用案例类而不是元组/三元组将使代码更易于阅读并减少错误
  • 这似乎是一个编程挑战,而不是真正的帮助请求。请将问题限制在您需要解决的真正问题上。谢谢。

标签: scala functional-programming foldleft


【解决方案1】:

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

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

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

【讨论】:

  • 或者,不区分大小写:grades.groupBy(._1).mapValues(.map(tpl => (tpl._2,tpl._3)))
  • 感谢您的建议。挑战在于真正将自己限制在地图和过滤器上。
  • @LeoWagner 您接受的答案使用distinct:为什么distinct 可以但groupBy 不行?
【解决方案2】:
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))))

【讨论】:

  • 宁可使用.collect
猜你喜欢
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2018-08-21
相关资源
最近更新 更多