2009-12-16 72 views
3

我正在寻找斯卡拉2.7的collect方法,但我似乎无法找到适用的调用。有什么相当于collect,我可以在scala中使用吗?斯卡拉方法收集2.7

要清楚我正在寻找从列表中筛选元素并将筛选出来的元素映射到新类型。

+1

注意'filterMap'已更名为'collect'。 – 2010-03-24 02:09:38

回答

7

您可以使用flatMap(2.7中的完整方法签名是def flatMap[B](f : (A) => Iterable[B]) : List[B])。它宣布双方IterableIterator(略有不同的签名):

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 
+0

我想这会比'Some'中的所有包装都产生更多的对象而不是'collect'。除此之外,这个'flatMap'和'collect'的使用还有什么区别吗? – 2013-05-01 13:04:26

1
scala> List(-1,-2, 1,2,3).filter{i => (i % 2) == 0}.map{i => i/2} 

line10: scala.List[scala.Int] = List(-1,1) 

你需要独立出来的两个电话

a very useful blog

+2

你根本不需要分开电话 – 2009-12-16 09:48:42

7

使用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) 
+0

你可以叫我*克里斯*,丹尼尔! – 2009-12-16 11:53:05

+0

或者单行:'for(i < - 1 to 10 if i%2 == 0)yield i * 2' – retronym 2010-03-24 06:26:43

+0

@retronym足够真实,尽管有某些模式匹配不能使用过滤器。例如(也许,唯一),类型检查。 – 2010-03-24 10:12:49