2

マルチマップトレイトを使用するマップがあるので、特定の値 でこのマップをフィルタリングすることと、一致する結果をフォームのタプルのリストにフラット化する
val multiMap = new HashMap[Foo, Set[Bar]] with MultiMap[Foo, Bar]
ことを組み合わせたいと思います 。これを行う慣用的な方法は何でしょうか。私はScalaがループせずにこれを行うためのアナモルフィズムのようなものを提供することを望んでいましたが、完全な初心者として、私のオプションが何であるかわかりません。
multiMap.values.filter(bar => barCondition)

val fooBarPairs: List[(Foo, Bar)]

4

3 に答える 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-expressionを使用することだと思います。

for {
  (str, xs) <- mm.toSeq
  x         <- xs
  if x > 10
} yield (str, x)      // = ArrayBuffer((Two,222), (Two,22), (One,11))

またはが必要です。そうでない.toSeq場合、出力タイプはになります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

もう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 に答える