我正在寻找Scala 2.7中的“collect”方法,但似乎找不到适用的调用。是否有类似于“collect”的东西可以在Scala中使用?
明确一下,我想要从列表中过滤元素,并将这些过滤器映射到新类型。
明确一下,我想要从列表中过滤元素,并将这些过滤器映射到新类型。
您可以使用flatMap
方法(2.7版本的完整方法签名为 def flatMap[B](f: (A) => Iterable[B]): List[B]
)。它在Iterable
和Iterator
上都声明了(具有略微不同的签名):
scala> val l = List("1", "Hello", "2")
l: List[java.lang.String] = List(1, Hello, 2)
scala> val ints = l.flatMap { s => try { Some(s.toInt) } catch { case _ => None } }
ints: List[Int] = List(1, 2)
Predef
中的一个显式转换option2iterable
。它在2.8版本中在TraversableLike
中声明:def flatMap[B, That](f: A => Traversable[B])(implicit bf: CanBuildFrom[Repr, B, That]): That
collect
创建更多对象,因为它会将所有内容都包装在Some
中。除此之外,使用flatMap
和collect
还有其他的区别吗? - Cristian Vrabie通常我使用 flatMap
/Option
,就像Chris所描述的那样,但有时有一种更复杂的选择,它更加令人愉悦:
class Filter[A](f: Any => Option[A]) {
def unapply(a: Any) = f(a)
}
object Filter {
def apply[A](f: Any => Option[A]) = new Filter(f)
}
val evens = Filter {
case n: Int if n % 2 == 0 => Some(n)
case _ => None
}
使用方法:
scala> for (evens(n) <- List.range(0,10)) yield n
res0: List[Int] = List(0, 2, 4, 6, 8)
for (i <- 1 to 10 if i % 2 == 0) yield i * 2
- retronymfor { a@(x: Int) <- Seq(1, "1", 2, "2") if a % 2 == 0} yield a
。如您所知,#900阻止了for { x: Int <- ...
。奇怪的是, for { a@(_: Int) <-
不起作用。 - retronymscala> List(-1,-2, 1,2,3).filter{i => (i % 2) == 0}.map{i => i / 2}
line10: scala.List[scala.Int] = List(-1,1)
你需要将这两个调用分开
filterMap
已更名为collect
。 - Daniel C. Sobral