Qual è la differenza tra le funzioni map
e flatMap
di Iterable
?scala Iterable # map vs. Iterable # flatMap
risposta
Ecco una buona spiegazione:
http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-2
Utilizzando lista come esempio: firma
del Map è:
map [B](f : (A) => B) : List[B]
e flatMap di è
flatMap [B](f : (A) => Iterable[B]) : List[B]
Quindi flatMap accetta un tipo [A] e restituisce un tipo iterabile [B] e mappa assume un tipo [A] e restituisce un tipo [B]
Questo ti darà anche un'idea che flatmap si "appiattirà" elenchi.
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)
Da scaladoc:
- mappa
restituisce iterable risultante dall'applicazione della funzione data f per ogni elemento di questo iterabile.
- flatMap
applica la funzione data f a ciascun elemento di questo iterabile, quindi concatena i risultati.
Sto cercando un po 'più di analisi/spiegazione. –
OK, quindi cambia la tua domanda in modo più specifico. Di 'ciò che già sai e di cosa hai bisogno di chiarire. – skaffman
Mi è piaciuto il tuo commento snippy meglio. –
Guardate qui: http://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-2
"Cerca flatMap" - c'è davvero una buona spiegazione di lì. (Fondamentalmente si tratta di una combinazione di "appiattimento" e "mappa" - caratteristiche di altre lingue).
Quanto sopra è tutto vero, ma c'è una cosa che è a portata di mano: flatMap
trasforma un List[Option[A]]
in List[A]
, con qualsiasi Option
che entra in profondità per None
, rimosso. Questa è una svolta concettuale chiave per andare oltre l'utilizzo di null
.
Aw, questo è un altro bel trucco con Option Non ci ho mai pensato. Ho appena avuto un metodo per restituire un elenco di 1 o più elementi, mai visto il metodo 'Option.toList': Elenco (alcuni (" pippo "), Nessuno, Alcuni (" barra ")) .flatMap (_.toList) –
O forse ancora meglio, usa "Option.toIterator" con il metodo di Tristan in modo da non scorrere l'intera lista finché necessario. – jkschneider
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
si può vedere questo meglio in espressioni for:
for {line <- lines
word <- line split "\\W+"}
yield word.length
questo si traduce in:
lines.flatMap(line => line.split("\\W+").map(word => word.length))
Ogni iteratore all'interno per sarà tradotto in un "flatMap", tranne l'ultimo uno, che viene tradotto in una "mappa".In questo modo, invece di restituire le raccolte nidificate (una lista di una matrice di un buffer di blah, blah, blah), si restituisce una collezione piatta. Una raccolta formata dagli elementi che vengono resi: una lista di interi, in questo caso.
È interessante notare che 'l flatMap {x => x}' è * precisamente * equivalente a 'l.flatten' secondo gli assiomi monadici. FlatMap è l'equivalente di Scala dell'operazione monadica 'bind' (>> = in Haskell). Trovo che sia più utile su monade non di raccolta come Opzione. Quando è in congiunzione con le raccolte, è molto utile per implementare "i loop della mappa nidificati", restituendo di conseguenza una collezione. –
Ben detto. Il concatenamento di Opzioni è molto più efficace di un insieme di istruzioni come if (x! = Null e x.foo! = Null). http://blog.lostlake.org/index.php?/archives/50-The-Scala-Option-class-and-how-lift-uses-it.html discute questo in dettaglio – agilefall
println (l.flatMap (x => x)) questo non funziona più e flatMap deve essere usato in questo modo: http://aperiodic.net/phil/scala/s-99/p07.scala –