【问题标题】:How to group by elements of tuple in Scala and map to list of new elements?如何在Scala中按元组元素分组并映射到新元素列表?
【发布时间】:2020-04-06 00:28:12
【问题描述】:

为了更好地理解高阶函数,我进行了一些 Scala 练习。我有以下问题,我无法理解如何解决。我有以下清单:

val input = List((1,"a"), (1,"b"), (1,"c"), (2,"d"), (2,"y"), (2,"e"), (3, "u"), (3,"a"), (3,"d"))

我想从此列表中创建一个 Map,它将 input 列表中遇到的每个字母映射到以前与该字母在同一个元组中的所有数字的列表。示例输出:

Map(a -> List(1,3), b->List(1), c->List(1), d->List(2,3), y->List(2), e->List(2), u->List(3)

到目前为止我尝试过的是:

val output = input.groupBy(_._2)

但是这会作为输出:

Map(e -> List((2,e)), y -> List((2,y)), u -> List((3,u)), a -> List((1,a), (3,a)), b -> List((1,b)), c -> List((1,c)), d -> List((2,d), (3,d)))

有人可以帮助我了解如何解决这个问题吗?感谢任何帮助,因为我是函数式编程的新手

【问题讨论】:

  • 你可以将结果映射到_._1
  • @sinanspd 你的意思是val output = input.groupBy(_._2).map(_._1)?
  • @AndriyPlokhotnyuk 你真的不会厌倦每次可以发布的吗?
  • 我希望修复它,但some forces are resisting that.

标签: list scala tuples higher-order-functions


【解决方案1】:

正如@sinanspd 所说:

input
  .groupBy {
    case (numer, letter) => letter
   } map {
     case (key, list) => key -> list.map {
       case (number, letter) => number
     }
   }

// Or equivalently
input.groupBy(_._2).view.mapValues(list => list.map(_._1)).toMap

// Or even simpler if you have access to Scala 2.13
input.groupMap(_._2)(_._1)

每次你想转换一些值的集合,其中转换是一对一的,你只需要一个map,所以在这种情况下,你想要转换Map的值由groupBy 返回,它们是 Lists,然后您希望将这些 Lists 的每个元素转换为只返回元组的第一个组件。所以它是另一个map 中的map

另外,Scaldoc 是您的朋友。通常,有很多有用的方法,例如mapValuesgroupMap

【讨论】:

    【解决方案2】:

    这是对我的评论的更详细解释。这是你需要做的:

    val output = input.groupBy(_._2).mapValues(_.map(_._1))
    

    重要的是要记住,在函数式编程中,我们喜欢纯函数。这意味着我们不会有不良的副作用,我们喜欢坚持one function one purpose principle

    这允许我们将这些纯函数链接起来并线性推理它们。我为什么要告诉你这些?虽然您的直觉可能是寻找或实现一个函数来执行此操作,但不要

    在这种情况下,我们首先按key进行分组,然后将取值List的每个值映射起来,并进行映射以提取元组的_._1。

    【讨论】:

      【解决方案3】:

      这是我能做的最好的,让它也排序,因为我看到其他响应没有排序,也许有人可以改进这个:

      import scala.collection.immutable.ListMap
      
      ListMap(input.groupBy(_._2).mapValues(_.map(_._1)).toSeq.sortBy(_._1):_*)
      

      【讨论】:

      • 最好使用SortedMap,但除非您想要maxmin 之类的东西,否则对Map 进行排序是没有意义的。跨度>
      猜你喜欢
      • 2021-11-26
      • 2017-08-09
      • 2016-02-10
      • 2017-08-24
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      相关资源
      最近更新 更多