Belajar Advanced Collection Function Lengkap di Kotlin
Kotlin Collection adalah salah satu struktur data mumpuni yang banyak menyediakan fungsi untuk memudahkan kita dalam mengelola dan memanipulasi data. Pada modul-modul sebelumnya, kita sudah mempelajari beberapa fungsi yang disediakan seperti map(), sum(), sorted(), dan sebagainya.
Pada modul ini kita akan mempelajari beberapa fungsi tingkat lanjut lainnya yang tentunya bisa kita manfaatkan untuk mengelola data seperti yang disebutkan di atas.
Fold
Langsung saja kita mulai dengan fungsi fold, kita bisa dengan mudah melakukan perhitungan setiap nilai yang berada di dalam sebuah collection tanpa harus melakukan iterasi item tersebut satu-persatu menggunakan fungsi fold(). Untuk contoh penggunaannya adalah sebagai berikut:
- val numbers = listOf(1, 2, 3)
- val fold = numbers.fold(10) { current, item ->
- println("current $current")
- println("item $item")
- println()
- current + item
- }
- println("Fold result: $fold")
- /*output:
- current 10
- item 1
- current 11
- item 2
- current 13
- item 3
- Fold result: 16
- */
Fungsi fold() memerlukan 2 (dua) argumen yaitu nilai awal untuk perhitungan dan lambda expression yang nilai kembaliannya digunakan untuk menentukan nilai awal selanjutnya.
Nah, di dalam lambda expression nya juga terdapat 2 (dua) argumen. Yaitu, argumen current yang merepresentasikan nilai awal dan argumen item merepresentasikan masing-masing item yang berada pada numbers.
Selain itu, terdapat juga fungsi fold lainnya yaitu foldRight().
Berbeda dengan fungsi fold(), fungsi foldRight() akan melakukan proses iterasi dari indeks terakhir dan posisi dari argumen pada lambda expression nya pun berbeda, di mana argumen item berada pada posisi pertama dan argumen current berada pada posisi kedua. Contohnya seperti berikut:
- val numbers = listOf(1, 2, 3)
- val fold = numbers.foldRight(10) { item, current ->
- println("current $current")
- println("item $item")
- println()
- item + current
- }
- println("Fold result: $fold")
- /*output:
- current 10
- item 3
- current 13
- item 2
- current 15
- item 1
- Fold result: 16
- */
Drop
Selanjutnya adalah fungsi drop(), fungsi yang bisa kita manfaatkan untuk memangkas item yang berada di dalam sebuah objek collection berdasarkan jumlah yang kita tentukan. Sebagai contoh, saat kita mempunyai sebuah collection seperti berikut:
- val number = listOf(1, 2, 3, 4, 5, 6)
Kemudian kita ingin memangkas 3 (tiga) item dari collection di atas. Dengan fungsi drop(), kita bisa melakukannya seperti di bawah ini:
- val number = listOf(1, 2, 3, 4, 5, 6)
- val drop = number.drop(3)
- println(drop)
- /*
- output: [4, 5, 6]
- */
Seperti yang dijelaskan sebelumnya, nilai 3 yang menjadi argumen dari fungsi drop() di atas adalah jumlah item yang akan dipangkas. Pemangkasan dimulai dari posisi atau indeks pertama, lalu bagaimana jika kita ingin memangkas nilai dari indeks terakhir? Kita bisa menggunakan fungsi dropLast(). Contohnya seperti berikut:
- val number = listOf(1, 2, 3, 4, 5, 6)
- val drop = number.dropLast(3)
- println(drop)
- /*
- output: [1, 2, 3]
- */
Take
Jika fungsi drop() digunakan untuk memangkas, fungsi take() bisa kita manfaatkan untuk menyaring item yang berada di dalam sebuah objek collection. Pemanggilan fungsi take() sama halnya seperti fungsi drop() di mana kita perlu menentukan jumlah item yang akan disaring. Berikut contoh penggunaannya:
- val total = listOf(1, 2, 3, 4, 5, 6)
- val take = total.take(3)
- println(take)
- /*
- output: [1, 2, 3]
- */
Kotlin juga menyediakan fungsi seperti dropLast() yang menjalankan operasi dari posisi atau indeks terakhir yaitu takeLast(). Contohnya seperti berikut:
- val total = listOf(1, 2, 3, 4, 5, 6)
- val take = total.takeLast(3)
- println(take)
- /*
- output: [4, 5, 6]
- */
Slice
Setelah pembahasan fungsi take() pada modul sebelumnya, muncul pertanyaan, bagaimana jika kita ingin menyaring item dari posisi tertentu?
Untuk itu kita bisa memanfaatkan fungsi slice(). Dalam penggunaannya, fungsi slice() membutuhkan sebuah argumen berupa Range yang digunakan untuk menentukan posisi pertama dan terakhir yang akan disaring. Berikut contohnya:
- val total = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
- val slice = total.slice(3..6)
- println(slice)
- /*
- output: [4, 5, 6, 7]
- */
Karena menggunakan Range, kita juga bisa menggunakan operator step ketika argumennya disematkan seperti berikut:
- val total = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
- val slice = total.slice(3..6 step 2)
- println(slice)
- /*
- output: [4, 6]
- */
Kemudian jika ingin menentukan posisi yang lebih spesifik, kita bisa mendefinisikannya di dalam sebuah collection, kemudian disematkan sebagai argumen. Misal seperti di bawah berikut:
- val index = listOf(2, 3, 5, 8)
- val total = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
- val slice = total.slice(index)
- println(slice)
- /*
- output: [3, 4, 6, 9]
- */
Kita harus berhati-hati dalam menentukan cakupan index untuk mendapatkan data. Karena dapat menyebabkan terjadinya ArrayIndexOutOfBoundsException jika posisi yang ditentukan tidak terdapat pada objek collection.
Distinct
Saat berurusan dengan item yang sama di dalam sebuah collection, untuk menyaring item yang sama tersebut kita akan melakukan iterasi dan membandingkan setiap itemnya.
Namun dengan Kotlin kita tidak perlu melakukannya secara manual, karena Kotlin Collection menyediakan fungsi untuk melakukannya dengan mudah yaitu fungsi distinct(). Sebagai contoh:
- val total = listOf(1, 2, 1, 3, 4, 5, 2, 3, 4, 5)
- val distinct = total.distinct()
- println(distinct)
- /*
- output: [1, 2, 3, 4, 5]
- */
Sama halnya seperti beberapa fungsi sebelumnya yang sudah dibahas, fungsi distinct() bisa langsung dipanggil dari objek collection. Kita juga bisa menggunakannya pada collection dengan tipe parameter seperti data class. Misal seperti berikut:
- data class Item(val key: String, val value: Any)
- val items = listOf(
- Item("1", "Kotlin"),
- Item("2", "is"),
- Item("3", "Awesome"),
- Item("3", "as"),
- Item("3", "Programming"),
- Item("3", "Language")
- )
- val distinctItems = items.distinctBy { it.key }
- distinctItems.forEach {
- println("${it.key} with value ${it.value}")
- }
- /*
- output:
- 1 with value Kotlin
- 2 with value is
- 3 with value Awesome
- */
Menariknya, kita bisa juga menentukan proses penyaringan item yang sama seperti apa yang akan dijalankan dengan menggunakan fungsi distinctBy(). Misal kita ingin menyaring item yang memiliki panjang sama, kita bisa melakukannya seperti berikut:
- val text = listOf("A", "B", "CC", "DD", "EEE", "F", "GGGG")
- val distinct = text.distinctBy {
- it.length
- }
- println(distinct)
- /*
- output: [A, CC, EEE, GGGG]
- */
Yang perlu diperhatikan, fungsi distinct() tidak dapat digunakan pada object Map Collection.
Chunked
Sama seperti fungsi split(), fungsi chunked() bisa kita gunakan untuk memecah nilai String menjadi beberapa bagian kecil dalam bentuk Array.
Namun untuk penerapannya sedikit berbeda, di mana fungsi split() membutuhkan argumen berupa RegEx sebagai parameter sedangkan chunked() membutuhkan nilai yang akan digunakan sebagai jumlah indeks untuk pemisah. Contoh penggunaannya seperti berikut:
- val word = "QWERTY"
- val chunked = word.chunked(3)
- println(chunked)
- /*
- output:[QWE, RTY]
- */
Selain itu, kita juga bisa menggunakannya untuk memodifikasi setiap nilai yang sudah dipecah. Contoh, hasil dari nilai yang sudah dipecah ingin kita buat menjadi huruf kecil, maka kita bisa menggunakan fungsi chunked() seperti berikut:
- val word = "QWERTY"
- val chunkedTransform = word.chunked(3) {
- it.toString().toLowerCase()
- }
- println(chunkedTransform)
- /*
- output: [qwe, rty]
- */
Argumen yang berada pada lambda expression di atas merepresentasikan setiap nilai yang sudah dipecah