Si j'ai quelque chose comme un List[Option[A]]
et je veux le convertir en List[A]
, la méthode standard consiste à utiliser flatMap
:
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)
Maintenant o => o
n'est qu'une fonction d'identité. J'aurais pensé qu'il y aurait un moyen de le faire:
l.flatMap(Identity) //return a List[String]
Cependant, je ne peux pas faire fonctionner cela car vous ne pouvez pas générer un object
. J'ai essayé plusieurs choses en vain; Quelqu'un at-il quelque chose comme ça au travail?
Il y a une identité fonction dans Predef .
l flatMap identity[Option[String]]
> List[String] = List(Hello, World)
Un pour l'expression est plus agréable, je suppose:
for(x <- l; y <- x) yield y
Modifier:
J'ai essayé de comprendre pourquoi le paramètre type (Option [String]) est nécessaire. Le problème semble être la conversion de type de l'option [T] en Iterable [T].
Si vous définissez la fonction d'identité comme:
l.flatMap( x => Option.option2Iterable(identity(x)))
le paramètre type peut être omis.
FWIW, sur Scala 2.8 vous appelez simplement flatten
dessus. Thomas est principalement couvert pour Scala 2.7 Il n’a manqué qu’une autre façon d’utiliser cette identité:
l.flatMap[String](identity)
Cependant, cela ne fonctionnera pas avec la notation d'opérateur (il semble que la notation d'opérateur n'accepte pas les paramètres de type, ce qui est bon à savoir).
Vous pouvez également appeler flatten
sur Scala 2.7 (sur un List
, au moins), mais il ne pourra rien faire sans type. Cependant, cela fonctionne:
l.flatten[String]
Vous pouvez juste aider un peu l'inférenceur de type:
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)