Sub*_*oid 24 maps functional-programming scala scalaz
说我有两张地图:
val a = Map(1 -> "one", 2 -> "two", 3 -> "three")
val b = Map(1 -> "un", 2 -> "deux", 3 -> "trois")
Run Code Online (Sandbox Code Playgroud)
我想通过键合并这些映射,应用一些函数来收集值(在这种特殊情况下,我想将它们收集到一个seq中,给出:
val c = Map(1 -> Seq("one", "un"), 2 -> Seq("two", "deux"), 3 -> Seq("three", "trois"))
Run Code Online (Sandbox Code Playgroud)
感觉应该有一个很好的,惯用的方式来做这个 - 任何建议?如果解决方案涉及scalaz,我很高兴.
Tra*_*own 21
scala.collection.immutable.IntMap
有一种intersectionWith
方法可以精确地做你想要的(我相信):
import scala.collection.immutable.IntMap
val a = IntMap(1 -> "one", 2 -> "two", 3 -> "three", 4 -> "four")
val b = IntMap(1 -> "un", 2 -> "deux", 3 -> "trois")
val merged = a.intersectionWith(b, (_, av, bv: String) => Seq(av, bv))
Run Code Online (Sandbox Code Playgroud)
这给了你IntMap(1 -> List(one, un), 2 -> List(two, deux), 3 -> List(three, trois))
.请注意,它正确地忽略了仅出现的键a
.
作为一个方面说明:我经常发现自己想要的unionWith
,intersectionWith
从等功能Haskell的Data.Map
斯卡拉.我认为没有任何原则性的理由,它们只应该IntMap
在基础collection.Map
特征上,而不是在基本特征中.
Inf*_*ity 19
val a = Map(1 -> "one", 2 -> "two", 3 -> "three")
val b = Map(1 -> "un", 2 -> "deux", 3 -> "trois")
val c = a.toList ++ b.toList
val d = c.groupBy(_._1).map{case(k, v) => k -> v.map(_._2).toSeq}
//res0: scala.collection.immutable.Map[Int,Seq[java.lang.String]] =
//Map((2,List(two, deux)), (1,List(one, un), (3,List(three, trois)))
Run Code Online (Sandbox Code Playgroud)
Ben*_*mes 14
Scalaz增加了一个方法|+|
的任何类型的A
针对其Semigroup[A]
可用.
如果您映射地图以使每个值都是单个元素序列,那么您可以非常简单地使用它:
scala> a.mapValues(Seq(_)) |+| b.mapValues(Seq(_))
res3: scala.collection.immutable.Map[Int,Seq[java.lang.String]] = Map(1 -> List(one, un), 2 -> List(two, deux), 3 -> List(three, trois))
Run Code Online (Sandbox Code Playgroud)