0Pricing
Kotlin Academy · Урок

filter, filterNot и partition

Разделяйте и выбирайте элементы с помощью функций на основе предикатов.

«filter, filterNot и partition» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Операции выбора

filter оставляет элементы, соответствующие предикату. filterNot оставляет элементы, которые ему НЕ соответствуют. Разбиение за один раз разделяет коллекцию на два списка.

Базовое применение filter

filter { ... } возвращает новый список, содержащий только элементы, для которых предикат имеет значение true.

fun main() {
    val nums = listOf(1, 2, 3, 4, 5, 6)
    val evens = nums.filter { it % 2 == 0 }
    println(evens) // [2, 4, 6]
}

filterNot

filterNot { ... } — обратная операция: оставляет элементы, для которых предикат имеет значение false. Результат такой же, как при инверсии предиката, но намерение выражено яснее.

fun main() {
    val nums = listOf(1, 2, 3, 4, 5, 6)
    val odds = nums.filterNot { it % 2 == 0 }
    println(odds) // [1, 3, 5]
}

Разбиение

partition возвращает Pair: сначала идут соответствующие элементы, затем несоответствующие. Это позволяет избежать двух проходов по данным.

fun main() {
    val nums = listOf(1, 2, 3, 4, 5, 6)
    val (evens, odds) = nums.partition { it % 2 == 0 }
    println("evens=$evens odds=$odds")
}

Разбиение с классом данных

Разделяйте список записей на две группы за один проход.

data class User(val name: String, val active: Boolean)
fun main() {
    val users = listOf(User("Ada", true), User("Ben", false), User("Cal", true))
    val (active, inactive) = users.partition { it.active }
    println("active=${active.map { it.name }}")
    println("inactive=${inactive.map { it.name }}")
}

filterIndexed

Предикат получает и индекс, и значение — это полезно, когда важна позиция.

fun main() {
    val nums = listOf(10, 20, 30, 40, 50)
    val every2nd = nums.filterIndexed { i, _ -> i % 2 == 0 }
    println(every2nd) // [10, 30, 50]
}

filterIsInstance

Оставляйте только элементы определённого типа — внутри выполняется интеллектуальное приведение типов.

fun main() {
    val mixed: List<Any> = listOf(1, "hello", 2.0, "world", 3)
    val onlyStrings = mixed.filterIsInstance<String>()
    println(onlyStrings) // [hello, world]
}

filterNotNull

Удаляйте значения null из списка допускающих null элементов — результатом будет список ненулевых элементов.

fun main() {
    val mixed: List<String?> = listOf("a", null, "b", null, "c")
    val nonNull = mixed.filterNotNull()
    println(nonNull) // [a, b, c]
}

Цепочка filter и map

Объединяйте filter и map в конвейерах выбора и преобразования.

data class Product(val name: String, val price: Double, val inStock: Boolean)
fun main() {
    val products = listOf(
        Product("Pen", 1.0, true),
        Product("Book", 12.0, false),
        Product("Lamp", 25.0, true)
    )
    val availableNames = products.filter { it.inStock }.map { it.name }
    println(availableNames) // [Pen, Lamp]
}

Отрицание с помощью filterNot для ясности

Иногда filterNot { it.isActive } читается лучше, чем filter { !it.isActive }.

data class Task(val title: String, val done: Boolean)
fun main() {
    val tasks = listOf(Task("Email", true), Task("Lunch", false), Task("Code", true))
    val pending = tasks.filterNot { it.done }
    println(pending) // [Task(title=Lunch, done=false)]
}

Разбиение возвращает списки

Pair из partition содержит два обычных списка — разберите их или обратитесь к ним через .first / .second.

fun main() {
    val nums = (1..10).toList()
    val result = nums.partition { it > 5 }
    println("above 5: ${result.first}")
    println("below 6: ${result.second}")
}

Разбиение и два вызова filter

Если нужны оба подмножества, partition работает быстрее: выполняется один проход вместо двух.

fun main() {
    val nums = (1..10).toList()
    // Two passes:
    val a = nums.filter { it > 5 }
    val b = nums.filter { it <= 5 }
    // One pass:
    val (c, d) = nums.partition { it > 5 }
    println("$a $b")
    println("$c $d")
}

Быстрая проверка

Какая функция за один проход возвращает BOTH соответствующие и несоответствующие элементы?

Повторение

filter выбирает соответствующие элементы; filterNot — несоответствующие; разбиение за один проход возвращает обе группы. Используйте filterIsInstance, чтобы оставить элементы определённого типа, и filterNotNull, чтобы удалить значения null. Объединяйте их с map для выбора и преобразования.

Часто задаваемые вопросы

Урок «filter, filterNot и partition» бесплатный?

Да — полный текст урока «filter, filterNot и partition» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «filter, filterNot и partition»?

Разделяйте и выбирайте элементы с помощью функций на основе предикатов. Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «filter, filterNot и partition»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. map и flatMap: преобразование каждого элемента
  2. filter, filterNot и partition
  3. fold, reduce и runningFold
  4. Цепочки конвейеров и отказ от промежуточных списков с Sequence
← Назад к Kotlin Academy