Получение частей коллекции
Стандартная библиотека Kotlin содержит расширяющие функции для получения частей коллекции. Эти функции предоставляют различные способы выбора элементов для результирующей коллекции: явное указание их позиций, задание размера результата и другие.
Фрагмент
slice() возвращает список элементов коллекции с заданными индексами. Индексы можно передать как диапазон или как коллекцию целых значений.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.slice(1..3))
println(numbers.slice(0..4 step 2))
println(numbers.slice(setOf(3, 5, 0)))
//sampleEnd
}
Взятие и удаление
Для получения заданного количества элементов, начиная с первого, используйте функцию take(). Для получения последних элементов используйте takeLast(). Если число задано больше размера коллекции, обе функции возвращают всю коллекцию.
Для взятия всех элементов, кроме заданного числа первых или последних элементов, используйте функции drop() и dropLast() соответственно.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.take(3))
println(numbers.takeLast(3))
println(numbers.drop(1))
println(numbers.dropLast(5))
//sampleEnd
}
Вы также можете использовать предикаты для определения количества элементов для взятия или удаления. Существует четыре функции, аналогичные описанным выше:
-
takeWhile()— этоtake()с предикатом: она берёт элементы до, но не включая первый, не соответствующий предикату. Если первый элемент коллекции не соответствует предикату, результат пустой. -
takeLastWhile()аналогичнаtakeLast(): она берёт диапазон элементов, соответствующих предикату, с конца коллекции. Первый элемент диапазона — элемент, следующий за последним элементом, не соответствующим предикату. Если последний элемент коллекции не соответствует предикату, результат пустой; -
dropWhile()— это противоположностьtakeWhile()с тем же предикатом: она возвращает элементы от первого, не соответствующего предикату, до конца. -
dropLastWhile()— это противоположностьtakeLastWhile()с тем же предикатом: она возвращает элементы с начала до последнего, не соответствующего предикату.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.takeWhile { !it.startsWith('f') })
println(numbers.takeLastWhile { it != "three" })
println(numbers.dropWhile { it.length == 3 })
println(numbers.dropLastWhile { it.contains('i') })
//sampleEnd
}
Разделение на куски
Для разделения коллекции на части заданного размера используйте функцию chunked(). chunked() принимает единственный аргумент — размер куска — и возвращает List из List заданного размера. Первый кусок начинается с первого элемента и содержит size элементов, второй кусок содержит следующие size элементов и так далее. Последний кусок может иметь меньший размер.
fun main() {
//sampleStart
val numbers = (0..13).toList()
println(numbers.chunked(3))
//sampleEnd
}
Вы также можете применить преобразование для возвращаемых кусков сразу. Для этого передайте преобразование в виде лямбда-функции при вызове chunked(). Аргументом лямбды является кусок коллекции. Когда chunked() вызывается с преобразованием, куски являются кратковременными List , которые должны быть обработаны прямо в этой лямбде.
fun main() {
//sampleStart
val numbers = (0..13).toList()
println(numbers.chunked(3) { it.sum() }) // `it` is a chunk of the original collection
//sampleEnd
}
Окна
Вы можете получить все возможные диапазоны элементов коллекции заданного размера. Функция для их получения называется windowed(): она возвращает список диапазонов элементов, которые вы бы увидели, рассматривая коллекцию через скользящее окно заданного размера. В отличие от chunked(), windowed() возвращает диапазоны элементов (окна), начиная с каждого элемента коллекции. Все окна возвращаются как элементы одного List.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four", "five")
println(numbers.windowed(3))
//sampleEnd
}
windowed() предоставляет больше гибкости с необязательными параметрами:
-
stepопределяет расстояние между первыми элементами двух смежных окон. По умолчанию значение равно 1, поэтому результат содержит окна, начинающиеся со всех элементов. Если вы увеличите шаг до 2, вы получите только окна, начинающиеся с нечётных элементов: первого, третьего и так далее. -
partialWindowsвключает окна меньших размеров, которые начинаются с элементов в конце коллекции. Например, если вы запрашиваете окна из трёх элементов, вы не можете создать их для последних двух элементов. ВключениеpartialWindowsв этом случае включает ещё два списка размеров 2 и 1.
Наконец, вы можете применить преобразование к возвращаемым диапазонам сразу. Для этого передайте преобразование в виде лямбда-функции при вызове windowed().
fun main() {
//sampleStart
val numbers = (1..10).toList()
println(numbers.windowed(3, step = 2, partialWindows = true))
println(numbers.windowed(3) { it.sum() })
//sampleEnd
}
Для создания окон из двух элементов существует отдельная функция - zipWithNext(). Она создаёт пары смежных элементов принимаемой коллекции. Обратите внимание, что zipWithNext() не разбивает коллекцию на пары; она создаёт Pair для каждого элемента, кроме последнего, поэтому её результат на [1, 2, 3, 4] — [[1, 2], [2, 3], [3, 4]], а не [[1, 2], [3, 4]]. zipWithNext() также может быть вызвана с функцией преобразования; она должна принимать два элемента принимаемой коллекции в качестве аргументов.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four", "five")
println(numbers.zipWithNext())
println(numbers.zipWithNext() { s1, s2 -> s1.length > s2.length})
//sampleEnd
}
© 2010–2020 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/reference/collection-parts.html