Spec-Zone.ru › Kotlin 1.7

Получение частей коллекции

Стандартная библиотека 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
}
Последнее изменение: 03 февраля 2022
Группировка Извлечение отдельных элементов

© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/collection-parts.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API