2010-02-07 96 views
20

假設您有一個列表(1,「1」)它是鍵入列表[任何],這當然是正確的和預期的。現在,如果我像這樣映射列表斯卡拉過濾器的集合類型

scala> List(1, "1") map { 
    | case x: Int => x 
    | case y: String => y.toInt 
    | } 

生成的類型是List [Int],這也是預期的。我的問題是如果有一個相當於過濾器的映射,因爲下面的例子將導致List [Any]。這可能嗎?我認爲這可以在編譯時解決,可能不是運行時?

scala> List(1, "1") filter { 
    | case x: Int => true 
    | case _ => false 
    | } 

回答

24

斯卡拉2.9:

scala> List(1, "1") collect { 
    | case x: Int => x 
    | } 
res0: List[Int] = List(1) 
1

關於修改後的問題,如果你只是使用保護的情況下,包括你的partialFunction,你會得到過濾:

scala> val l1 = List(1, 2, "three", 4, 5, true, 6) 
l1: List[Any] = List(1, 2, three, 4, 5, true, 6) 

scala> l1.partialMap { case i: Int if i % 2 == 0 => i } 
res0: List[Int] = List(2, 4, 6) 
+0

這是爲什麼只有警衛纔有可能? – 2010-02-08 21:08:06

+0

對不起,這是一個非常愚蠢的評論。但爲什麼filter()不生成像partialMap一樣的結果? – 2010-02-09 11:11:35

+1

@Joa'filter'不會更改集合的類型,因爲它不會修改其元素。 – 2010-02-09 15:29:25

6

對於任何人在這個問題上陷入困惑,想知道爲什麼最受讚譽的答案不適合他們,請注意在Scala 2.8的決賽之前partialMap方法被更名爲collect 發佈。試試這個:

scala> List(1, "1") collect { 
    | case x: Int => x 
    | } 
res0: List[Int] = List(1) 

(這真的應該對丹尼爾C.索布拉爾的,否則,精彩的回答評論,但作爲一個新的用戶,我不能沒有評論)