Scala集合类型用于过滤

20

假设你有一个类型为List[Any]的列表(1,"1"),这当然是正确和期望的。现在,如果我像这样映射列表

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

结果类型是List[Int],这也是预期的。我的问题是: 是否存在一种类似于map的filter方法,因为以下示例将导致List[Any]。这是可能的吗?我假设这可以在编译时解决,而不是运行时?

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

24

Scala 2.9:

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

6

对于那些偶然遇到这个问题并且最高票答案不适用于他们的人,请注意,在Scala 2.8正式发布之前,partialMap方法被重命名为collect。请尝试使用以下方法代替:

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

(这实际上应该是对Daniel C. Sobral的非常好的回答的评论,但作为新用户,我还不能发表评论。)

1
关于您修改后的问题,如果您在包含部分函数的情况下使用守卫,就可以进行过滤:
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)

为什么只有使用 guard 才能实现这一点? - Joa Ebert
抱歉,那是一个非常愚蠢的评论。但为什么filter()没有像partialMap一样生成结果呢? - Joa Ebert
1
@Joa的filter不会改变集合的类型,因为它不会修改其元素。 - Daniel C. Sobral
1
好的,filter只需要一个谓词,这使得编译器无法推断结果类型。而对于部分函数,它可以使用所有情况的结果类型,并计算这些类型的上限作为部分函数的整体类型。 - Randall Schulz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接