2009-12-16 109 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