我有一个使用 multimap 特征的地图,所以
val multiMap = new HashMap[Foo, Set[Bar]] with MultiMap[Foo, Bar]
我想结合过滤特定值的地图
multiMap.values.filter(bar => barCondition)
与将匹配结果展平为形式的元组列表
val fooBarPairs: List[(Foo, Bar)]
什么是这样做的惯用方式?我希望 Scala 可以提供类似变形的东西来做到这一点而无需循环,但作为一个完整的新手,我不确定我的选择是什么。
问问题
896 次
3 回答
4
这是一个例子:
import collection.mutable.{HashMap, MultiMap, Set}
val mm = new HashMap[String, Set[Int]] with MultiMap[String, Int]
mm.addBinding("One", 1).addBinding("One",11).addBinding("Two",22).
addBinding("Two",222)
// mm.type = Map(Two -> Set(22, 222), One -> Set(1, 11))
我认为获得所需内容的最简单方法是使用 for 表达式:
for {
(str, xs) <- mm.toSeq
x <- xs
if x > 10
} yield (str, x) // = ArrayBuffer((Two,222), (Two,22), (One,11))
您需要.toSeq
or 输出类型将是 a Map
,这意味着每个映射都被后续元素覆盖。toList
如果您特别需要,请在此输出上使用List
。
于 2012-07-22T11:13:58.353 回答
1
这是我认为你想要做的一个例子:
scala> mm
res21: scala.collection.mutable.HashMap[String,scala.collection.mutable.Set[Int]] with scala.collection.mutable.MultiMap[String,Int]
= Map(two -> Set(6, 4, 5), one -> Set(2, 1, 3))
scala> mm.toList.flatMap(pair =>
pair._2.toList.flatMap(bar =>
if (bar%2==0)
Some((pair._1, bar))
else
None))
res22: List[(String, Int)] = List((two,6), (two,4), (one,2))
于 2012-07-22T11:18:49.427 回答
1
这是另一个更简洁的解决方案:
import collection.mutable.{HashMap, MultiMap, Set}
val mm = new HashMap[String, Set[Int]] with MultiMap[String, Int]
val f = (i: Int) => i > 10
mm.addBinding("One", 1)
.addBinding("One",11)
.addBinding("Two",22)
.addBinding("Two",222)
/* Map(Two -> Set(22, 222), One -> Set(1, 11)) */
mm.map{case (k, vs) => vs.filter(f).map((k, _))}.flatten
/* ArrayBuffer((Two,222), (Two,22), (One,11)) */
于 2012-07-22T12:23:17.357 回答