Шаг 230.
Основы Kotlin. Основы функционального программирования. Задания для самостоятельного решения
На этом шаге мы приведем несколько практических заданий с возможными решениями.
Здесь мы предлагаем вам выполнить несколько заданий, направленных на закрепление изученного материала.
Задание 1: переворачиваем значения в ассоциативном массиве
Используя функциональные техники, изученные на предыдущих шагах, напишите функцию с именем flipValues(), которая позволит менять местами ключ и значение в
ассоциативном массиве. Например:
val gradesByStudent = mapOf("Josh" to 4.0, "Alex" to 2.0, "Jane" to 3.0)
{Josh=4.0, Alex=2.0, Jane=3.0}
flipValues(gradesByStudent)
{4.0=Josh, 2.0=Alex, 3.0=Jane}
Раскрыть/скрыть решение и комментарии.
Функция, решающая данную задачу, может быть такой:
fun flipValues (grBySt: Map<String, Double>): Map<Double, String>{
val gBSt = grBySt
.map { it -> Pair(it.value, it.key) }.toMap()
return gBSt
}
Прокомментируем приведенный текст.
Функция принимает ассоциативный маассив (тип Map<String, Double>) и возвращает тоже ассоциативный массив, в котором ключ и значение поменяны местами
(тип Map<Double, String>).
Для того, чтобы получить доступ к каждому элементу, используем функцию-преобразователь map(). Для доступа к очередному элементу используем it. Это элемент ассоциативного
массива. Конструкция Pair(it.value, it.key) позволяет поменять местами ключ и значение.
Результатом работы map() является список. Функция toMap() преобразует его в ассоциативный массив.
Результат работы функции приведен на рисунке 1.
Рис.1. Результат работы функции
Задание 2: скользящее окно
Для этого продвинутого задания нам понадобится список значений:
val valuesToAdd = listOf(1, 18, 73, 3, 44, 6, 1, 33, 2, 22, 5, 7)
Используя приемы функционального программирования, выполните следующие операции над списком valuesToAdd:
- Исключите все числа меньше 5.
- Сгруппируйте числа в пары.
- Перемножьте числа в каждой паре.
- Сложите произведения и выведите получившееся число.
Правильный ответ: 2339. Вот как должны выглядеть результаты на каждом шаге:
Step 1: 1, 18, 73, 3, 44, 6, 1, 33, 2, 22, 5, 7
Step 2: 18, 73, 44, 6, 33, 22, 5, 7
Step 3: [18*73], [44*6], [33*22], [5*7]
Step 4: 1314 + 264 + 726 + 35 = 2339
Обратите внимание, что шаг 3 группирует список в подсписки из двух элементов каждый. Этот алгоритм известен также как "скользящее окно" (отсюда и название задания).
Чтобы выполнить это непростое задание, вам понадобится обратиться к документации Kotlin, а именно к описанию функций коллекций:
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/. Удачи!
Раскрыть/скрыть решение и комментарии.
Последовательность шагов мы оформили в виде следующей функции:
fun funZad(numbers: List<Int>) {
val num1 = numbers.filter{ it > 4 }
println("Step1: $num1")
val num2 = num1.windowed(2, 2).map {
(one, two) -> "[$one*$two]"
}
println("Step2: $num2")
val num3 = num1.windowed(2, 2).map {
(one, two) -> one * two
}
println("Step3: $num3")
val num4 = num3.fold(0) {
accumulator, number ->
accumulator + number
}
println("Step4: $num4")
}
Рис.2. Текст функции
Результат ее выполнения с указанным начальным значением несколько отличается от заданного.
Step1: [18, 73, 44, 6, 33, 22, 5, 7]
Step2: [[18*73], [44*6], [33*22], [5*7]]
Step3: [1314, 264, 726, 35]
Step4: 2339
Рис.3. Результат работы функции
Первое задание - использование конструкции filter(). Надеемся, что предложенное решение не вызвало затруднений.
Наибольший интерес вызывает второй шаг.
С помощью функции windowed() вы можете получить все возможные диапазоны элементов коллекции. Представьте, что вы смотрите на коллекцию через "окно" определённого
размера. Это окно может скользить от начала до конца коллекции, тем самым последовательно выделяя каждый возможный её диапазон. Функция windowed() возвращает диапазоны
(или окна), в которых первым элементом является каждый последующий элемент коллекции, а размер диапазона равен размеру "окна". Все диапазоны возвращаются в качестве элементов
одного списка. Первый параметр - это размер окна. Второй параметр (step) определяет расстояние между первыми элементами соседних диапазонов. По умолчанию равен 1, поэтому в этом
случае результат будет содержать диапазоны, начинающиеся со всех элементов коллекции. Если вы зададите шаг равный 2, то получите диапазоны, начинающиеся только с нечётных
элементов: 1, 3 и т.д.
Последний результат достигается использованием функции fold(). Начальное значение, равное 0, присваивается переменной accumulator. Затем очередное значение (number)
складывается с accumulator, после чего полученная сумма отправляется снова в accumulator.
Со следующего шага мы начнем рассматривать совместимость с Java.
Предыдущий шаг
Содержание
Следующий шаг