Iterable.filter în Kotlin

Creează o listă nouă doar cu elementele care îndeplinesc condiția (filterNot: cu cele care nu o îndeplinesc).

Sintaxă
fun <T> Iterable<T>.filter(conditie: (T) -> Boolean): List<T>
fun <T> Iterable<T>.filterNot(conditie: (T) -> Boolean): List<T>
fun <T> Iterable<T>.filterIndexed(conditie: (index: Int, T) -> Boolean): List<T>

Ce face Iterable.filter

filter verifică fiecare element cu funcția dată și păstrează doar elementele pentru care rezultatul este true. Ordinea se păstrează, iar lista originală nu se schimbă.

filterNot face opusul: păstrează elementele pentru care condiția este false. Este mai ușor de citit decât filter { !(...) }. filterIndexed primește și poziția elementului, util pentru „fiecare al doilea element” sau „primele poziții”.

Pe un Map, filter primește perechi (it.key, it.value) și întoarce tot un Map.

Parametri

Parametru Descriere
conditie Funcție care întoarce true pentru elementele de păstrat (la filterNot, pentru cele de eliminat).

Ce returnează

O List<T> nouă, posibil goală.

Exemple

Exemplul 1: Elevi promovați și corigenți

Aceeași condiție folosită în două feluri: filter păstrează notele de trecere, filterNot pe celelalte.

fun main() {
    val note = mapOf("Ana" to 9, "Ion" to 4, "Maria" to 7, "Vlad" to 3)
    val trecut = { nota: Int -> nota >= 5 }

    val promovati = note.entries.filter { trecut(it.value) }.map { it.key }
    val corigenti = note.entries.filterNot { trecut(it.value) }.map { it.key }

    println("Promovați: $promovati")
    println("Corigenți: $corigenti")
}

Rezultat

Promovați: [Ana, Maria]
Corigenți: [Ion, Vlad]

Exemplul 2: Filtrare după mai multe condiții

Condiția poate fi oricât de complexă, cât timp întoarce Boolean.

data class Apartament(val cartier: String, val camere: Int, val pret: Int)

fun main() {
    val anunturi = listOf(
        Apartament("Copou", 2, 82_000),
        Apartament("Tătărași", 3, 95_000),
        Apartament("Copou", 3, 120_000),
        Apartament("Nicolina", 2, 70_000),
    )
    val potrivite = anunturi.filter { it.camere >= 2 && it.pret <= 100_000 && it.cartier != "Nicolina" }
    potrivite.forEach { println(it) }
}

Rezultat

Apartament(cartier=Copou, camere=2, pret=82000)
Apartament(cartier=Tătărași, camere=3, pret=95000)

Exemplul 3: filterIndexed: elementele de pe poziții pare

Păstrăm pozițiile 0, 2, 4…, adică fiecare al doilea element, începând cu primul.

fun main() {
    val ture = listOf("Ana", "Bogdan", "Carmen", "Dan", "Elena")
    val echipaA = ture.filterIndexed { index, _ -> index % 2 == 0 }
    val echipaB = ture.filterIndexed { index, _ -> index % 2 == 1 }
    println("Echipa A: $echipaA")
    println("Echipa B: $echipaB")
}

Rezultat

Echipa A: [Ana, Carmen, Elena]
Echipa B: [Bogdan, Dan]

Greșeli frecvente

  • Te aștepți ca filter să scoată elemente din lista originală. Întoarce o listă nouă; pentru a modifica lista folosește removeAll / retainAll pe o MutableList.
  • Folosești filter { ... }.first() doar ca să găsești un element. first { ... } sau find { ... } se opresc la primul găsit și nu creează o listă intermediară.

Comenzi înrudite

  • Iterable.map: Creează o listă nouă în care fiecare element este rezultatul funcției aplicate elementului original.
  • Iterable.partition: Împarte colecția în două liste: elementele care îndeplinesc condiția și cele care nu o îndeplinesc.
  • Iterable.find: Întoarce primul element care îndeplinește condiția sau null dacă nu există niciunul.
  • Iterable.filterNotNull: Întoarce o listă nouă fără elementele null; tipul rezultatului nu mai permite null.
  • Iterable.count: Numără elementele colecției sau doar pe cele care îndeplinesc o condiție.
  • MutableCollection.removeAll: Șterge pe loc toate elementele care îndeplinesc o condiție (removeAll, removeIf) sau păstrează doar pe cele care o îndeplinesc (retainAll).