2010-02-07 57 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.索布拉尔的,否则,精彩的回答评论,但作为一个新的用户,我不能没有评论)