본문 바로가기
Android (Kotlin)/kotlin 문법

[Kotlin] List - forEach

by 키윤 2023. 12. 4.

우선적으로 사용할 데이터가 아래 코드와 같다고 가정하자.

class Country(val name : String, val cities : List<City>)

class City(val name : String, val streets : List<String>)

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))))
}

1.

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

2.

1번에서는 파라미터를 explicit하게 작성하였다. : c->
it을 사용하면 explicit 부분 생략이 가능하다.

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

3.

2번이랑 같은 코드 explicit하게 작성되었다. (이렇게 작성해도된다.)

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

4.

나라명, 도시명, 도로명을 모두 출력하는 코드이다. 첫번째 사용된 it은 나라명를 지칭하고, 두번째 it은 도시명 그리고 세번째 it은 도로명를 지칭한다. it이 중복되어 사용되고 지칭하는 값이 변하기 때문에 6번째 줄에 it.name 을 작성할 수 없다. 만약에 nesting 끝자락에 전에 있었던 값을 사용하고 싶다면 코드를 5번처럼 작성해야한다.

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

5.

it 말고 다른 파라미터를 도입해주어야 한다. it이 아닌 경우에는explicit하게 적어줘야한다.

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

6.

Nested loop은 가독성이 떨어지기 때문에 가능한 한 사용하지 않는것이 좋다. flatMap을 대신 사용하여 출력할 수 있다.

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

7.

nested flatMap을 사용하지 않고 작성하는 또다른 코드이다. 확장자를 이용하는 방법인데 확장자 공부를 해봐야겠다.

fun City.getStreetsWithCityName() : List<String> {
    return streets.map { "$name, $it" }
      .toList()
}

fun Country.getCitiesWithCountryName() : List<String> {
    return cities.flatMap { it.getStreetsWithCityName() }
      .map { "$name, $it" }
}

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

 

출처: https://www.baeldung.com/kotlin/nested-foreach