Котлин Заметки
карта()
map()
— это функция расширения в Kotlin, которая определяется как:
fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R>
Эта функция обычно полезна в ситуациях взаимного сопоставления. Например, предположим, что каждый заказ состоит из множества строк заказа в качестве подробных позиций покупки:
class Order(val name: String, val price: Int)
Теперь, если у нас есть Order
, мы можем использовать map()
, чтобы найти название каждого элемента:
val orders = listOf( Order("Tomato", 2), Order("Garlic", 3), Order("Chives", 2) ) val names = order.map { it.name } println(names) [Tomato, Garlic, Chives]
Здесь мы преобразуем List<Order>
в List<String>
, передав простую функцию преобразования. Эта функция принимает все Order
в качестве входных данных (переменная it
) и преобразует их в String
. В качестве другого примера, мы можем рассчитать общую стоимость Order
следующим образом:
val totalPrice = orders.map { it.price }.sum() println(totalPrice) 7
По сути, map()
эквивалентен следующему императивному стилю кодирования:
val result = mutableListOf<R>() for (each in this) { result += transform(each) }
Когда мы используем map()
, нам просто нужно написать часть transform
. Определение новой коллекции, итерация и добавление каждого преобразованного элемента в эту коллекцию — это всего лишь шаблонный код и часть деталей реализации.
плоская карта ()
В отличие от map()
, flatMap()
обычно используется для выравнивания отношений "один ко многим".
fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R>
В качестве примера предположим, что у нас есть коллекция заказов, и мы собираемся найти все отдельные имена элементов:
// List<List<Order>> val orderLists = listOf( listOf(Order("Garlic", 1), Order("Chives", 2)), listOf(Order("Tomato", 1), Order("Garlic", 2)), listOf(Order("Potato", 1), Order("Chives", 2)) )
Поскольку здесь нам нужно свести List<Order>
к отдельным Order
, мы можем использовать функцию flatMap()
:
val orders: List<Order> = orderLists.flatMap { it } val names = orders.map { it.name }.distinct() println(names) [Garlic, Chives, Tomato, Potato]
Как показано выше, функция flatMap()
сводит отношение "один ко многим" к одному List<Order>
.
Эквивалент flatMap()
в императивном стиле выглядит примерно так:
val result = mutableListOf<OrderLine>() for (order in orders) { val transformedList = order.lines for (individual in transformedList) { result += individual } }
Заключение
Подводя итог, map()
обычно полезен для сопоставлений один к одному, а flatMap()
более полезен для выравнивания сопоставлений один ко многим.