Für jeden in Kotlin verschachtelt

1. Einleitung

In diesem kurzen Kotlin-Tutorial sehen wir uns den Parameterbereich im Lambda einer forEach- Schleife an.

Zunächst definieren wir die Daten, die wir in unseren Beispielen verwenden. Zweitens werden wir sehen, wie Sie mit forEach eine Liste durchlaufen. Drittens werden wir uns ansehen, wie es in verschachtelten Schleifen verwendet wird.

2. Testdaten

Die Daten, die wir verwenden, sind eine Liste von Ländern, die jeweils eine Liste von Städten enthalten, die wiederum eine Liste von Straßen enthalten:

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. Einfach für jeden

Um den Namen jedes Landes in der Liste auszudrucken, können wir den folgenden Code schreiben:

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

Die obige Syntax ähnelt Java. Wenn das Lambda in Kotlin jedoch nur einen Parameter akzeptiert, können wir ihn als Standardparameternamen verwenden und müssen ihn nicht explizit benennen:

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

Das Obige ist auch gleichbedeutend mit:

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

Es lohnt sich , zu beachten Sie, dass wir nur können sie als implizite Parameter - Namen , wenn kein expliziter Parameter ist.

Zum Beispiel funktioniert Folgendes nicht:

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

Und beim Kompilieren wird ein Fehler angezeigt:

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

4. Für jeden verschachtelt

Wenn wir alle Länder, Städte und Straßen durchlaufen möchten, können wir eine verschachtelte Schleife schreiben:

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

Hier ist der erste es bezieht sich auf ein Land, das zweite es zu einer Stadt und der dritte es auf einer Straße.

Wenn wir jedoch IntelliJ verwenden, wird eine Warnung angezeigt:

Implicit parameter 'it' of enclosing lambda is shadowed

Dies mag kein Problem sein, aber in Zeile 6 können wir uns nicht mehr auf das Land oder die Stadt beziehen. Wenn wir das wollen, müssen wir den Parameter explizit benennen :

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

5. Alternativen zu verschachtelten Schleifen

Verschachtelte Schleifen sind im Allgemeinen schwer zu lesen und sollten nach Möglichkeit vermieden werden. Eine Möglichkeit ist die Verwendung von flatMap () :

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

Wenn wir jedoch keine verschachtelte flatMap verwenden , können wir in der println- Anweisung nicht auf den Stadt- oder Straßennamen zugreifen . Wenn wir dieselbe Ausgabe wie in der obigen Methode allTable () haben und das Verschachteln vermeiden möchten , können wir zwei Erweiterungsfunktionen hinzufügen:

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

Verwenden Sie dann diese beiden Methoden mit einer einzigen flatMap :

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

6. Fazit

In diesem kurzen Artikel, sahen wir , wie die Standard - Parameter verwenden es in Kotlin und wie die Parameter eines äußeren zuzugreifen forEach aus einer verschachtelten forEach Schleife. Schließlich haben wir uns auch mit der Vermeidung verschachtelter Schleifen mit flatMap- und Erweiterungsfunktionen befasst.

Alle Codefragmente in diesem Artikel finden Sie in unserem GitHub-Repository.