2009-11-25 154 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)