dans https://try.kotlinlang.org/#/Kotlin%20Koans/Collections/FlatMap/Task.kt
il a un exemple d'utilisation de flatMap
et map
semble que les deux font la même chose, existe-t-il un exemple montrant la différence entre flatMap
et map
?
le type de données:
data class Shop(val name: String, val customers: List<Customer>)
data class Customer(val name: String, val city: City, val orders: List<Order>) {
override fun toString() = "$name from ${city.name}"
}
data class Order(val products: List<Product>, val isDelivered: Boolean)
data class Product(val name: String, val price: Double) {
override fun toString() = "'$name' for $price"
}
data class City(val name: String) {
override fun toString() = name
}
les échantillons:
fun Shop.getCitiesCustomersAreFrom(): Set<City> =
customers.map { it.city }.toSet()
// would it be same with customers.flatMap { it.city }.toSet() ?
val Customer.orderedProducts: Set<Product> get() {
return orders.flatMap { it.products }.toSet()
// would it be same with return orders.map { it.products }.toSet()
}
Prenons l'exemple suivant. Vous avez une structure de données simple Data
avec une seule propriété de type List
.
class Data(val items : List<String>)
fun main(args: Array<String>) {
val data = listOf(Data(listOf("a", "b", "c")), Data(listOf("1", "2", "3")))
val items: List<String> = data.flatMap { it.items } //[a, b, c, 1, 2, 3]
val items2: List<List<String>> = data.map { it.items } //[[a, b, c], [1, 2, 3]]
}
flatMap
contre map
Avec flatMap
, vous pouvez "aplatir" plusieurs Data::items
dans une collection, comme indiqué avec la variable items
. Utiliser map
, par contre, donne simplement une liste de listes.
flatMap
Notez qu'il existe une extension flatten
sur Iterable<Iterable<T>>
et aussi Array<Array<T>>
que vous pouvez utiliser alternativement pour flatMap
:
val nestedCollections: List<Int> = listOf(listOf(1,2,3), listOf(5,4,3)).flatten()
Il y a trois fonctions en jeu ici. map (), flatten (), et flatMap () qui est une combinaison des deux premiers.
data class Hero (val name:String)
data class Universe (val heroes: List<Hero>)
val batman = Hero("Bruce Wayne")
val wonderWoman = Hero (name = "Diana Prince")
val mailMan = Hero("Stan Lee")
val deadPool = Hero("Wade Winston Wilson")
val marvel = Universe(listOf(mailMan, deadPool))
val dc = Universe(listOf(batman, wonderWoman))
val allHeroes: List<Universe> = listOf(marvel, dc)
allHeroes.map { it.heroes }
// output: [[Hero(name=Stan Lee), Hero(name=Wade Winston Wilson)], [Hero(name=Bruce Wayne), Hero(name=Diana Prince)]]
Map vous permet d'accéder à chaque univers de {allHeroes} et (dans ce cas) de retourner sa liste de héros. La sortie sera donc une liste contenant deux listes de héros, une pour chaque univers. Le résultat est une liste>
allHeroes.flatMap { it.heroes }
// output: [Hero(name=Stan Lee), Hero(name=Wade Winston Wilson), Hero(name=Bruce Wayne), Hero(name=Diana Prince)]
FlatMap vous permet de faire la même chose que map, d’accéder aux deux listes de héros des deux univers. Mais cela va plus loin et aplatit la liste de listes renvoyée en une liste unique. Le résultat est une liste
allHeroes.map { it.heroes }.flatten()
// output: [Hero(name=Stan Lee), Hero(name=Wade Winston Wilson), Hero(name=Bruce Wayne), Hero(name=Diana Prince)]
Cela produit le même résultat que flatMap. Donc flatMap est une combinaison des deux fonctions, map {} puis flatten ()