2012-08-07 42 views
31

我已經搜索了一下,但尚未找到一個很好的答案,但尚未找到有關如何篩選出值爲無的映射的任何條目。說我有一個圖是這樣的:無數值的篩選器映射

val map = Map[String, Option[Int]]("one" -> Some(1), 
            "two" -> Some(2), 
            "three" -> None) 

我想最終返回只用("one", Some(1))("two", Some(2))對地圖。我明白,當你有一個列表時,這是通過拼合來完成的,但我不確定如何在不將分割成鍵和值的情況下實現對地圖的效果,然後嘗試重新加入它們。

回答

34

就像在scala.collection名稱空間中的每Map集合類型具有定義的filter方法和Option具有isDefined方法,該方法是trueSomefalseNone

scala> map.filter(_._2.isDefined) 
res4: scala.collection.immutable.Map[String,Option[Int]] = Map(one -> Some(1), two -> Some(2)) 
+0

Neato。我不會猜到語法。還是有點困惑'_.'從我的理解,我們告訴它去第一個(當前)對的第二項(值)? – KChaloux 2012-08-07 21:47:54

+2

@KChaloux在這種情況下'_'是指傳遞給'filter'方法的函數文本的第一個參數。這是'x => x._2.isDefined'的縮寫, – 2012-08-07 22:13:25

+0

而_2來自[Tuple](http://www.scala-lang.org/api/current/index.html#scala.Tuple2)。 – fracz 2015-11-01 19:48:13

41

如果你過濾掉None值,你還不如在同一時間提取Some值與Map[String,Int]落得:

您可以通過合併這兩個過濾掉 None
scala> map.collect { case (key, Some(value)) => (key, value) } 
res0: scala.collection.immutable.Map[String,Int] = Map(one -> 1, two -> 2) 
+0

非常酷,我一定會檢查出來。 – KChaloux 2012-08-08 13:41:17

+1

我想你可以離開toMap :-) – 2014-08-22 14:44:27

6

另外 map.filterKeys(map(_) != None)

for((k,v) <- map if(v!= None)) yield (k,v)

此方法提供了地圖上不存在的常規filterValues方法。
我錯過了這樣的方法,因爲沒有任何替代方案是完美的。

[稍後更新]這是一個更好的版本,它不會對每個條目執行查找,並且仍然可以合理清晰地讀取。

map.filter({case (x,y)=> y!=None})