2009-06-29 16 views

Respuesta

42

Aquí es una explicación bastante buena:

http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-2

lista Usando como ejemplo: la firma

del Mapa es:

map [B](f : (A) => B) : List[B] 

y flatMap de es

flatMap [B](f : (A) => Iterable[B]) : List[B] 

Así que flatMap toma un tipo [A] y devuelve un tipo iterable [B] y el mapa toma un tipo [A] y devuelve un tipo [B]

Esto también le dará una idea de que flatmap se "aplanará" liza.

val l = List(List(1,2,3), List(2,3,4)) 

println(l.map(_.toString)) // changes type from list to string 
// prints List(List(1, 2, 3), List(2, 3, 4)) 

println(l.flatMap(x => x)) // "changes" type list to iterable 
// prints List(1, 2, 3, 2, 3, 4) 
+12

Es interesante notar que 'l flatMap {x => x}' es * precisamente * equivalente a 'l.flatten' de acuerdo con los axiomas monádicos. FlatMap es el equivalente de Scala de la operación monadic 'bind' (>> = en Haskell). Encuentro que es más útil en mónadas que no sean colecciones, como Option. Cuando se combina con las colecciones, es más útil para implementar "bucles de mapa anidados" y devolver una colección como resultado. –

+0

Bien dicho. El encadenamiento de opciones es mucho mejor para trabajar que un conjunto de sentencias como if (x! = Null y x.foo! = Null). http://blog.lostlake.org/index.php?/archives/50-The-Scala-Option-class-and-how-lift-uses-it.html discute esto en detalle – agilefall

+1

println (l.flatMap (x => x)) esto ya no funciona y se necesita usar flatMap así: http://aperiodic.net/phil/scala/s-99/p07.scala –

8

De scaladoc:

  • mapa

Devuelve el iterable resultante de la aplicación de la función dada f a cada elemento de este iterable.

  • flatMap

aplica la función dada f a cada elemento de esta iterable, entonces concatena los resultados.

+0

Estoy buscando un poco más de análisis/explicación. –

+0

OK, así que cambie su pregunta para ser más específico. Di lo que ya sabes y lo que necesitas aclarar. – skaffman

+5

Me gustó tu comentario snippy mejor. –

54

Lo anterior es cierto, pero hay una cosa más que es muy práctico: flatMap convierte en un List[Option[A]]List[A], con cualquier Option que profundiza hasta llegar a None, eliminado. Este es un avance conceptual clave para ir más allá del uso de null.

+3

Aw, ese es otro buen truco con Option Nunca pensé en eso. Acabo de tener un método para devolver una lista de 1 o más cosas, nunca vi el método 'Option.toList': Lista (Algunos (" foo "), Ninguno, Algunos (" barra ")) .flatMap (_.toList) –

+0

O tal vez incluso mejor, use 'Option.toIterator' con el método de Tristan para que no itere sobre toda la lista hasta que sea necesario. – jkschneider

8
lines.map(line => line split "\\W+") // will return a list of arrays of words 
lines.flatMap(line => line split "\\W+") // will return a list of words 

Esto se puede ver mejor en de comprensiones:

for {line <- lines 
    word <- line split "\\W+"} 
yield word.length 

esto se traduce en:

lines.flatMap(line => line.split("\\W+").map(word => word.length)) 

Cada repetidor interior para que se traducirá en una "flatMap", excepto el último uno, que se traduce en un "mapa".De esta forma, en lugar de devolver colecciones anidadas (una lista de una matriz de un búfer de bla, bla, bla), devuelve una colección plana. Una colección formada por los elementos que se ceden - una lista de enteros, en este caso.

Cuestiones relacionadas