簡體   English   中英

過濾Scala Multimap並輸出為元組列表

[英]Filtering a Scala Multimap and outputting as a list of Tuples

我有一個使用多圖特征的地圖,像這樣
val multiMap = new HashMap[Foo, Set[Bar]] with MultiMap[Foo, Bar]
我想結合過濾此地圖上的特定值
multiMap.values.filter(bar => barCondition)
將匹配結果展平為以下形式的元組列表
val fooBarPairs: List[(Foo, Bar)]
這樣做的慣用方式是什么? 我希望Scala可以提供類似變形的功能而無需循環,但是作為一個完整的新手,我不確定我的選擇是什么。

這是一個例子:

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否則輸出類型將是Map ,這意味着每個映射都被后續元素覆蓋。 如果您特別需要List請在此輸出上使用toList

這是我想做的一個例子:

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))

這是另一個更簡潔的解決方案:

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)) */

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM