在 Scala 中,Map 是否有等价于 Haskell 的 "fromListWith"?

In Scala, is there an equivalent of Haskell's "fromListWith" for Map?

在Haskell中,有一个叫做fromListWith的函数,它可以从一个函数(用于合并具有相同键的值)和一个列表生成一个Map:

fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

以下表达式的计算结果为 true:

fromListWith (++) [(5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a")] == fromList [(3, "ab"), (5, "aba")]

在Scala中,在List对象上也有一个类似的函数叫toMap,它也可以将列表转换为Map,但是不能有函数的参数来处理重复的键。

有人对此有想法吗?

stdlib 没有这样的功能,但是,在 scalaz 中有一个 Data.Map 端口可用,does have 这个功能可用。

除了使用scalaz你也可以自己定义一个:

implicit class ListToMapWith[K, V](list: List[(K, V)]) {
  def toMapWith(op: (V, V) => V) = 
    list groupBy (_._1) mapValues (_ map (_._2) reduce op)
}

这是一个用法示例:

scala> val testList = List((5,"a"), (5,"b"), (3,"b"), (3,"a"), (5,"a"))
scala> testList toMapWith (_ + _)
res1: scala.collection.immutable.Map[Int,String] = Map(5 -> aba, 3 -> ba)