Iterable.mapNotNull în Kotlin

Aplică o funcție fiecărui element și păstrează doar rezultatele care nu sunt null; firstNotNullOf întoarce primul astfel de rezultat.

Sintaxă
fun <T, R : Any> Iterable<T>.mapNotNull(transformare: (T) -> R?): List<R>
fun <T, R : Any> Iterable<T>.firstNotNullOf(transformare: (T) -> R?): R   // Kotlin 1.5

Ce face Iterable.mapNotNull

mapNotNull este map urmat de filterNotNull, într-un singur pas. Funcția ta întoarce fie o valoare, fie null pentru elementele care nu trebuie păstrate. Este perfect pentru conversii care pot eșua, de exemplu toIntOrNull().

firstNotNullOf se oprește la primul element pentru care funcția nu dă null și întoarce acel rezultat. Dacă nu există niciunul, aruncă NoSuchElementException. Varianta sigură este firstNotNullOfOrNull, care întoarce null.

Parametri

Parametru Descriere
transformare Funcția aplicată fiecărui element; rezultatul null înseamnă „sari peste”.

Ce returnează

mapNotNull: o listă cu rezultatele nenule. firstNotNullOf: primul rezultat nenul.

Exemple

Exemplul 1: Numere citite dintr-un formular

Textele care nu sunt numere dau null la toIntOrNull() și dispar din rezultat.

fun main() {
    val campuri = listOf("12", "abc", "7", "", "30", "3,5")
    val numere = campuri.mapNotNull { it.toIntOrNull() }
    println(numere)
    println("Suma: ${numere.sum()}")
}

Rezultat

[12, 7, 30]
Suma: 49

Exemplul 2: Primul oraș cunoscut

Căutăm codul poștal în ordinea preferințelor. firstNotNullOf se oprește la primul oraș pentru care avem cod.

fun main() {
    val coduri = mapOf("Iași" to "700001", "Cluj" to "400001")
    val preferinte = listOf("Sibiu", "Cluj", "Iași")

    val cod = preferinte.firstNotNullOf { coduri[it] }
    println("Primul cod găsit: $cod")

    val niciunul = listOf("Arad", "Deva").firstNotNullOfOrNull { coduri[it] }
    println("Pentru Arad/Deva: $niciunul")
}

Rezultat

Primul cod găsit: 400001
Pentru Arad/Deva: null

Greșeli frecvente

  • Scrii map { it.toIntOrNull() }.filter { it != null }: rezultatul are tot tipul List<Int?>. Cu mapNotNull tipul devine List<Int>.
  • Folosești firstNotNullOf când e posibil să nu existe niciun rezultat: programul se oprește cu excepție. Folosește firstNotNullOfOrNull.

Comenzi înrudite

  • Iterable.map: Creează o listă nouă în care fiecare element este rezultatul funcției aplicate elementului original.
  • Iterable.filterNotNull: Întoarce o listă nouă fără elementele null; tipul rezultatului nu mai permite null.
  • listOfNotNull: Creează o listă doar cu valorile care nu sunt null; elementele null sunt sărite.
  • Iterable.find: Întoarce primul element care îndeplinește condiția sau null dacă nu există niciunul.