Bersarang untuk Setiap di Kotlin

1. Pengenalan

Dalam tutorial Kotlin pendek ini, kita akan melihat skop parameter di dalam lambda forEach loop.

Pertama, kami menentukan data yang akan kami gunakan dalam contoh kami. Kedua, kita akan melihat bagaimana menggunakan forEach untuk mengulang senarai. Ketiga, kita akan melihat cara menggunakannya dalam gelung bersarang.

2. Data Ujian

Data yang akan kami gunakan adalah senarai negara, masing-masing berisi senarai kota, yang pada gilirannya, berisi senarai jalan:

class Country(val name : String, val cities : List) class City(val name : String, val streets : List) class World { val streetsOfAmsterdam = listOf("Herengracht", "Prinsengracht") val streetsOfBerlin = listOf("Unter den Linden","Tiergarten") val streetsOfMaastricht = listOf("Grote Gracht", "Vrijthof") val countries = listOf( Country("Netherlands", listOf(City("Maastricht", streetsOfMaastricht), City("Amsterdam", streetsOfAmsterdam))), Country("Germany", listOf(City("Berlin", streetsOfBerlin)))) } 

3. Mudah foreach

Untuk mencetak nama setiap negara dalam senarai, kita boleh menulis kod berikut:

fun allCountriesExplicit() { countries.forEach { c -> println(c.name) } } 

Sintaks di atas serupa dengan Java. Walau bagaimanapun, dalam Kotlin, jika lambda menerima hanya satu parameter, kita boleh menggunakan ia sebagai nama parameter lalai dan tidak perlu untuk menamakan ia jelas:

fun allCountriesIt() { countries.forEach { println(it.name) } }

Perkara di atas juga bersamaan dengan:

fun allCountriesItExplicit() { countries.forEach { it -> println(it.name) } } 

Ia berbaloi untuk ambil perhatian bahawa kami hanya boleh menggunakan ia sebagai nama parameter tersirat jika tidak ada parameter yang jelas.

Contohnya, perkara berikut tidak berfungsi:

fun allCountriesExplicit() { countries.forEach { c -> println(it.name) } } 

Dan kita akan melihat ralat pada waktu kompilasi:

Error:(2, 38) Kotlin: Unresolved reference: it 

4. Bersarang untukSetiap

Sekiranya kita ingin melakukan iterasi di semua negara, bandar, dan jalan, kita dapat menulis gelung bersarang:

fun allNested() { countries.forEach { println(it.name) it.cities.forEach { println(" ${it.name}") it.streets.forEach { println(" $it") } } } } 

Di sini, pertama ia merujuk kepada sebuah negara, kedua ia ke bandar dan yang ketiga ia ke jalan.

Namun, jika kita menggunakan IntelliJ, kita melihat peringatan:

Implicit parameter 'it' of enclosing lambda is shadowed

Ini mungkin tidak menjadi masalah, tetapi, di baris 6 kita tidak dapat merujuk negara atau bandar lagi. Sekiranya kita menginginkannya, kita perlu memberi nama parameter secara jelas :

fun allTable() { countries.forEach { c -> c.cities.forEach { p -> p.streets.forEach { println("${c.name} ${p.name} $it") } } } } 

5. Alternatif untuk Gelung Bersarang

Gelung bersarang umumnya sukar dibaca dan harus dielakkan jika boleh. Salah satu pilihan adalah menggunakan flatMap () :

fun allStreetsFlatMap() { countries.flatMap { it.cities} .flatMap { it.streets} .forEach { println(it) } }

Namun, jika kita tidak menggunakan flatMap bersarang , kita tidak dapat mengakses nama kota atau jalan dalam pernyataan println . Sekiranya kita ingin mempunyai output yang sama seperti pada metode di atas allTable () dan mengelakkan bersarang, kita dapat menambahkan dua fungsi sambungan:

fun City.getStreetsWithCityName() : List { return streets.map { "$name, $it" } .toList() } fun Country.getCitiesWithCountryName() : List { return cities.flatMap { it.getStreetsWithCityName() } .map { "$name, $it" } }

Kemudian gunakan dua kaedah ini dengan flatMap tunggal :

fun allFlatMapTable() { countries.flatMap { it.getCitiesWithCountryName() } .forEach { println(it) } }

6. Kesimpulannya

Dalam artikel singkat ini, kita melihat bagaimana untuk menggunakan lalai parameter ia dalam Kotlin dan bagaimana untuk mengakses parameter yang luar foreach dari dalam bersarang foreach gelung. Akhirnya, kami juga melihat bagaimana untuk mengelakkan gelung bersarang menggunakan fungsi flatMap dan extension.

Semua coretan kod dalam artikel ini boleh didapati di repositori GitHub kami.