首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala连接列表中的映射

Scala连接列表中的映射
EN

Stack Overflow用户
提问于 2015-07-10 13:07:40
回答 1查看 174关注 0票数 0

有了val mapList: List[Map[String, Int]],我想做这样的事情:

代码语言:javascript
复制
val map = mapList foldLeft (Map[String, Int]()) ( _ ++ _ )

代码语言:javascript
复制
val map = mapList foldLeft (Map[String, Int]())
 ( (m1: Map[String, Int], m2: Map[String, Int]) => m1 ++ m2 )

两个选项都没有编译(第一个选项是“扩展函数(x, y) => x ++ y缺少的参数类型”,第二个选项是“类型不匹配;找到(Map[String, Int], Map[String, Int]) => Map[String, Int];必需的:String")。

我想要实现一个经典的解决方案,用于连接一个不可变映射列表,比如List( Map("apple" -> 5, "pear" -> 7), Map("pear" -> 3, "apricot" -> 0) )将生成一个Map("apple" -> 5, "pear" -> 10, "apricot" -> 0)

使用scala 2.10.5

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-10 13:12:47

您需要在foldLeft之前添加一个点。在特殊情况下,只能使用空格而不是点,例如对于具有确切1参数的方法(arity-1方法):

代码语言:javascript
复制
val map = mapList.foldLeft(Map[String, Int]()) ( _ ++ _ )

您可以阅读更多关于方法调用最佳实践这里的内容。

您还可能对reduce方法感兴趣,这些方法是fold方法的专门版本,其中返回类型与集合元素的类型相同。例如,reduceLeft使用集合的第一个元素作为foldLeft的种子。当然,由于这依赖于第一个元素的存在,如果集合为空,它将抛出异常。由于reduceLeft只接受一个参数,所以您可以更容易地使用空间来调用该方法:

代码语言:javascript
复制
mapList.reduceLeft( _ ++ _)
mapList reduceLeft(_ ++ _)

最后,您应该注意到,您在这里所做的就是合并映射。当使用++合并映射时,您只需覆盖映射中已经存在的键,- you就不会添加重复键的值。如果您想这样做,您可以按照提供的答案这里,并将它们应用到foldLeftreduceLeft。例如:

代码语言:javascript
复制
mapList reduceLeft { (acc, next) => 
    (acc.toList ++ next.toList).groupBy(_._1).toMap.mapValues(_.map(_._2).sum) 
}

或略有不同:

代码语言:javascript
复制
mapList.map(_.toSeq).reduceLeft(_ ++ _).groupBy(_._1).toMap.mapValues(_.map(_._2).sum)

而且,如果您正在使用Scalaz,那么最简洁的是:

代码语言:javascript
复制
mapList reduceLeft { _ |+| _ }
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31341592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档