【问题标题】:Summing and grouping map values in Scala在 Scala 中对映射值进行求和和分组
【发布时间】:2012-10-26 09:49:07
【问题描述】:

我是 Scala 的新手,我正在寻找一种更简洁的方法来对映射值进行求和和分组。有没有比下面的代码更好的方法:

def mapSum(thisMap: Map[Char, Int], thatMap: Map[Char, Int]) = {
  thisMap.transform { (k, v) => thatMap(k) + v }
}

满足以下测试:

@Test
def mapSum() {
  val map: Map[Char, Int] = Map('C' -> 1, 'D' -> 3)
  val newMap = mapSum(map, map)
  assertEquals(2, newMap('C'))
  assertEquals(6, newMap('D'))
}

【问题讨论】:

  • 您是否假设地图始终具有相同的键?
  • 如果他们不这样做(如您正在学习的 coursera 课程中),您应该使用.withDefault
  • @TravisBrown 是的,他们总是有相同的键。
  • @KimStebel 我没有参加 coursera 课程,我只是在玩 Akka 并编写一个简单的应用程序,不过谢谢。
  • 有趣的是,这完全符合本周作业的一部分

标签: scala dictionary collections grouping aggregation


【解决方案1】:

如果您想要简洁,使用标准库的当前版本不会比您的当前版本好多少(但请注意,您可以去掉外括号以使其成为两行代码)。

Scalaz 提供了一些工具,可以让这种事情变得更简洁一些,包括Map 的一个幺半群实例和一个拉皮条的unionWith 方法:

scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._

scala> val m = Map('C' -> 1, 'D' -> 3)
m: scala.collection.immutable.Map[Char,Int] = Map(C -> 1, D -> 3)

scala> m |+| m
res0: scala.collection.immutable.Map[Char,Int] = Map(C -> 2, D -> 6)

scala> (m unionWith m)(_ + _)
res1: Map[Char,Int] = Map(C -> 2, D -> 6)

请注意,这两种方法的行为与您的略有不同 - 如果第一个中的键不在第二个中,它们不会在运行时阻塞,并且它们不会默默地忽略第二个不在第一个中。

【讨论】:

  • 我觉得不错,谢谢!在这种情况下,我不需要它来处理丢失的密钥,但这种解决方案在防御性编程方面更好。
  • @Caps 这使用了一个名为 scalaz 的外部库......不值得引入这种依赖关系只是为了将您的代码减少几个字符。当然,使用预先编写的函数会很简洁,但导入你自己编写的函数也是如此。
  • @LuigiPlinge:我希望我似乎没有试图隐瞒这涉及外部库的事实! (当然还有许多其他使用 Scalaz 的理由。)
  • 别担心,它没有;我之所以这么说是因为 Caps 提到他是新手,可能没有意识到大多数项目都不使用 scalaz。
  • @LuigiPlinge 是的,我意识到 Scalaz 是一个外部库,我只是想检查是否有更简洁的方法来表达该函数,并且看起来没有使用外部函数标准 Scala 库,所以我接受它作为答案。干杯!
猜你喜欢
  • 2022-01-26
  • 1970-01-01
  • 2011-02-15
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 2023-01-14
  • 1970-01-01
相关资源
最近更新 更多