2009-11-25 81 views
58

如果我有像一個List[Option[A]],我想這個轉換成List[A],標準的方法是使用flatMap是否有scala身份識別功能?

scala> val l = List(Some("Hello"), None, Some("World")) 
l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World)) 

scala> l.flatMap(o => o) 
res0: List[java.lang.String] = List(Hello, World) 

現在o => o只是一個身份的功能。我本來還以爲是什麼一些方法來做到:

l.flatMap(Identity) //return a List[String] 

但是,我不能得到這個工作,因爲你不能泛型化的object。我嘗試了幾件事情無濟於事。有沒有人有這樣的工作?

+2

我會認爲'{_}'應該等同於'{X => X}'就像'{_ + 3}'等同於{x => x + 3}'一樣。任何人都可以評論爲什麼它不是這樣嗎? – 2016-12-06 01:38:31

回答

52

有一個身份function in Predef

l flatMap identity[Option[String]] 

> List[String] = List(Hello, World) 

一種用於expresion是更好的,我想:

for(x <- l; y <- x) yield y 

編輯:

我試圖找出爲什麼需要該類型參數(選項[字符串])。問題似乎是從Option [T]到Iterable [T]的類型轉換。

如果定義爲標識功能:

l.flatMap(x => Option.option2Iterable(identity(x))) 

類型參數可以省略。

+0

類型推理器怎麼會不知道類型本身?爲什麼'l.flatMap(identity):List [String]'沒有工作? – 2009-11-25 15:37:25

+0

我認爲推理者可以弄清楚。我不知道。我會添加一個問題。 :-) – 2009-11-25 15:42:57

+1

@oxbow_lakes - 查看編輯。它與隱式類型轉換有關。 – 2009-11-25 16:22:15

21

FWIW,在斯卡拉2.8上,你只需撥打flatten就可以了。 Thomas它主要覆蓋Scala 2.7。他只錯過了利用身份的一種替代方法:

l.flatMap[String](identity) 

它不會與運營商的符號工作,但是(似乎算符不接受類型的參數,這是很好的瞭解)。

可以呼叫flatten上的Scala 2.7(在List,至少),但它不能做任何事情沒有一個類型。然而,這個工程:

l.flatten[String] 
2

你可以給類型inferencer一點幫助:

scala> val l = List(Some("Hello"), None, Some("World")) 
l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World)) 

scala> l.flatten[String] 
res0: List[String] = List(Hello, World)