Получение частей коллекции
Стандартная библиотека 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–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/collection-parts.html