На этом шаге мы рассмотрим комбинаторы.
Третья категория функций, используемых в функциональном программировании, - это комбинаторы. Функции-комбинаторы принимают разные коллекции и объединяют их в одну новую. (В отличие от них flatMap() принимает одну коллекцию, которая содержит другие коллекции.) Введите следующий код в Kotlin REPL.
val employees = listOf("Denny", "Claudette", "Peter") val shirtSize = listOf("large", "x-large", "medium") val employeeShirtSizes = employees.zip(shirtSize).toMap() println(employeeShirtSizes["Denny"])
Рис.1. Комбинирование двух коллекций, функциональный стиль (REPL)
В этом примере вы применили функцию-комбинатор zip(), чтобы объединить два списка: с именами сотрудников и их размерами одежды. Функция zip() возвращает новый список, коллекцию пар Pair. Для этой коллекции пар вы затем вызываете функцию toMap(), чтобы получить ассоциативный массив, к элементам которого можно обращаться по ключу. В этом случае ключ - имя работника.
Другая функция, полезная для комбинирования значений, - fold(). Функция fold() принимает начальное накопленное значение, которое обновляется в соответствии с результатом анонимной функции, вызываемой для каждого элемента в коллекции. Затем накопленное значение передается следующей анонимной функции. Рассмотрим следующий пример, где функция fold() используется для вычисления суммы чисел в списке, умноженных на 3:
val foldedValue = listOf(1, 2, 3, 4).fold(0) { accumulator, number -> println("Accumulated value: $accumulator") accumulator + (number * 3) } println("Final value: $foldedValue")
Рис.2. Использование функции fold() (REPL)
Если вы запустите этот код, то получите следующий результат (рисунок 2):
Accumulated value: 0 Accumulated value: 3 Accumulated value: 9 Accumulated value: 18 Final value: 30
Начальное значение 0 передается в анонимную функцию, которая выводит его как Accumulated value: 0. Это значение 0 передается далее в вычисление с первым элементом списка, 1, и выводится результат Accumulated value: 3 (так как 0+(1*3)). Затем к накопленному значению 3 прибавляется (2*3) и выводится результат Accumulated value: 9 и т. д. После обхода всех элементов, выводится итоговое накопленное значение.
На следующем шаге мы рассмотрим преимущества функционального программирования.