Kotlin menyediakan fungsi transformasi untuk membentuk collection baru dari collection yang sudah ada, tanpa perulangan yang ditulis manual. Topik ini membahas map untuk mengubah setiap elemen, filter untuk menyaring, flatMap untuk meratakan collection bertingkat, serta associate, associateBy, dan associateWith untuk membentuk Map. Seluruh contoh memakai data nilai ujian dan dijalankan dengan compiler Kotlin, sehingga keluarannya dapat direproduksi di lingkungan yang sama.
map dan filter#
Fungsi map menerapkan satu lambda pada setiap elemen dan mengumpulkan hasilnya menjadi List baru dengan jumlah elemen yang sama. Bentuknya nilai.map { ... }, dan variabel it di dalam lambda menunjuk elemen yang sedang diproses. Fungsi filter melakukan sebaliknya, yaitu mempertahankan elemen yang lulus kondisi lambda dan membuang sisanya, sehingga jumlah elemen hasilnya bisa lebih sedikit. Keduanya membentuk objek baru dan tidak menyentuh collection asalnya. Program berikut membandingkan keduanya pada data nilai ujian.
fun main() {
val nilai = listOf(80, 65, 90, 55, 75)
val lulus = nilai.filter { it >= 75 }
println(lulus)
val status = nilai.map { if (it >= 75) "lulus" else "remidi" }
println(status)
val rincian = nilai.filter { it >= 75 }.map { "nilai $it" }
println(rincian)
}# compiler Kotlin dan pustaka standar yang dipakai jalur ini
export PATH=/home/kal/my-project/tools/kotlinc/bin:/home/kal/my-project/tools/jdk-merged/bin:$PATH
export STDLIB=/home/kal/my-project/tools/kotlinc/lib/kotlin-stdlib.jar
# kompilasi main.kt menjadi out.jar, lalu jalankan programnya
kotlinc main.kt -d out.jar && java -cp "out.jar:$STDLIB" MainKt[80, 90, 75]
[lulus, remidi, lulus, remidi, lulus]
[nilai 80, nilai 90, nilai 75]Pemanggilan filter { it >= 75 } menghasilkan [80, 90, 75], sedangkan map dengan percabangan di dalam lambdanya menghasilkan lima label karena jumlah elemennya tetap. Baris ketiga merangkai keduanya, yaitu hasil filter langsung dipetakan oleh map menjadi string. Hasil akhirnya berupa List baru, sedangkan nilai tetap berisi lima angka aslinya. Lambda yang isinya satu ekspresi seperti it >= 75 adalah bentuk yang paling umum pada fungsi transformasi.
flatMap untuk collection bertingkat#
Fungsi flatMap menggabungkan dua langkah menjadi satu, yaitu mengubah setiap elemen menjadi collection lalu menyatukan seluruh hasilnya menjadi satu List. Fungsi map saja akan menghasilkan List berisi List, sedangkan flatMap meratakannya satu tingkat. Bentuk ini cocok untuk data yang terkelompok secara alami, misalnya nilai ujian yang tersimpan per kelas. Program berikut meratakan nilai dua kelas menjadi satu daftar.
fun main() {
val kelasA = listOf(80, 75, 90)
val kelasB = listOf(65, 85, 70)
val perKelas = listOf(kelasA, kelasB)
println(perKelas)
val semuaNilai = perKelas.flatMap { it }
println(semuaNilai)
val predikat = semuaNilai.filter { it >= 75 }.map { "lulus: $it" }
println(predikat)
}# kompilasi gabung.kt menjadi gabung.jar, lalu jalankan programnya
kotlinc gabung.kt -d gabung.jar && java -cp "gabung.jar:$STDLIB" GabungKt[[80, 75, 90], [65, 85, 70]]
[80, 75, 90, 65, 85, 70]
[lulus: 80, lulus: 75, lulus: 90, lulus: 85]Variabel perKelas bertipe List<List<Int>>, yaitu daftar yang elemennya juga daftar. Pemanggilan flatMap { it } melepas satu tingkat susunan sehingga seluruh nilai berada pada satu daftar, lalu rangkaian filter dan map pada baris berikutnya bekerja pada data yang sudah datar. Tanpa flatMap, langkah yang sama memerlukan perulangan bersarang atau penggabungan daftar secara manual. Lambda pada flatMap mengembalikan collection apa pun, dan seluruh hasilnya selalu digabung dalam satu tingkat.
associate untuk membentuk Map#
Ketiga fungsi associate membentuk Map dari sebuah collection. Fungsi associateWith menjadikan elemen sebagai kunci dan hasil lambda sebagai nilainya, sedangkan associateBy menjadikan hasil lambda sebagai kunci dan elemen sebagai nilainya. Fungsi associate memberi kebebasan penuh karena setiap elemen dikirim sebagai Pair berisi kunci dan nilai. Program berikut memakai ketiganya pada data nama dan nilai ujian.
fun main() {
val nama = listOf("Ali", "Budi", "Citra")
val panjang = nama.associateWith { it.length }
println(panjang)
val kata = listOf("api", "buku", "angin")
val perAwalan = kata.associateBy { it.first() }
println(perAwalan)
val pasangan = listOf("Ali" to 80, "Budi" to 90, "Citra" to 75)
val nilaiSiswa = pasangan.associate { it }
println(nilaiSiswa)
println(nilaiSiswa["Budi"])
}# kompilasi kamus.kt menjadi kamus.jar, lalu jalankan programnya
kotlinc kamus.kt -d kamus.jar && java -cp "kamus.jar:$STDLIB" KamusKt{Ali=3, Budi=4, Citra=5}
{a=angin, b=buku}
{Ali=80, Budi=90, Citra=75}
90Pemanggilan associateWith { it.length } menjadikan setiap nama sebagai kunci dengan panjangnya sebagai nilai, sedangkan associateBy { it.first() } menjadikan huruf awal sebagai kunci. Keluaran {a=angin, b=buku} memperlihatkan perilaku yang perlu diwaspadai, yaitu kata api dan angin sama-sama berkunci a, dan pasangan yang dikirim belakangan menimpa yang lebih dulu. Pemanggilan associate { it } pada daftar Pair langsung membentuk Map nama dan nilai, lalu nilainya dibaca dengan [] sebagaimana Map pada umumnya.
Ringkasan#
mapmenerapkan lambda pada setiap elemen dan menghasilkanListbaru dengan jumlah elemen yang sama, sedangkanfiltermempertahankan elemen yang lulus kondisinya.- Hasil transformasi selalu berupa collection baru, dan collection asalnya tidak berubah.
flatMapmengubah setiap elemen menjadi collection lalu meratakannya menjadi satuListsatu tingkat.associateWith,associateBy, danassociatemembentukMapdengan aturan kunci dan nilai yang berbeda, dan kunci ganda ditimpa tanpa pesan error.
Referensi#
- Collection operations — Kotlin Documentation
— Transformasi umum seperti
map,filter,flatMap, danassociatebeserta contohnya. - Collections overview — Kotlin Documentation — Posisi operasi transformasi di dalam keluarga collection Kotlin.