如何更改此选项以使用“for循环”而不是“forEach”

时间:2018-01-21 19:51:10

标签: kotlin

我正在努力改变它以使用for循环并仍然做同样的事情。

程序应该读取带有一些航班的文件,程序的这个特定部分需要使用用户输入的两天来读取文件,然后它需要显示每个航班和每天有多少乘客。

现在它是如何工作的,但是我正在尝试将其更改为使用for循环,正如我之前所说,但是不起作用,因为我不知道如何做与map相同的事情,但只是在fun interval

fun interval(reservas: List<Reservas>, dayInferior: Int, daySuperior: Int) {
    val map = mapReservas(reservas)
    for(day in dayInferior..daySuperior) {
        map.forEach {
            val reservasNum = it.key.first
            val reservasDay = it.key.second
            val reservasCount = it.value.count()
            if (reservasDay == day) {
                 println("$reservasNum has $reservasCount passengers on day $day")
            }
        }
    }
    println()
    println("Press Enter")                                                              
    readLine()
}

fun mapReservas(reservas: List<Reservas>): Map<Pair<String, Int>, List<Reservas>> {
    val map = mutableMapOf<Pair<String, Int>, MutableList<Reservas>>()
    for (reserva in reservas) {
        val key = reserva.numFlight to reserva.day
        val list = map[key] ?: mutableListOf()
        list.add(reserva)
        map[key] = list
    }
    return map
}

2 个答案:

答案 0 :(得分:3)

所有代码只能用一个函数替换。

fun interval(reservas: List<Reservas>, dayInferior: Int, daySuperior: Int) {
    reservas.groupBy { reserva -> reserva.day to reserva.numFlight }
        .filter { (key, _) -> key.first in dayInferior..daySuperior }
        .forEach { (key, reservas) ->
            val (reservasNum, reservasDay) = key
            val reservasCount = reservas.count()
            println("$reservasNum has $reservasCount passengers on day $reservasDay")
    }
    println()
    println("Press Enter")
    readLine()
}

解释

  1. 在我看来,首先您尝试按Reservasday对所有numFlight进行分组。它可以通过一个函数groupBy完成,您可以在其中传递daynumFlight对。
  2. 按天过滤所有Reservas。可以通过检查日期是否属于范围dayInferior..daySuperior(运营商in)。
  3. 来完成
  4. 使用forEach打印所有储存器。
  5. 其他事情

    1. Destructing declarations

      val reservasNum = it.key.first
      val reservasDay = it.key.second
      
      same as 
      
      val (reservasNum, reservasDa) = it.key
      
    2. Omitting one unused parameter in lamda

      .filter { (key, _) -> ... }
      

答案 1 :(得分:2)

如果在Map上使用for循环进行迭代,则每个元素都是Pair。如果您撰写(pair, list),则会对每个配对进行结构化,而配对本身包含PairList

fun interval(reservas: List<Reservas>, dayInferior: Int, daySuperior: Int) {
    val map = mapReservas(reservas)

    for(day in dayInferior..daySuperior) {

        for((pair, list) in map) {
            val reservasNum = pair.first
            val reservasDay = pair.second
            val reservasCount = list.count()
            // ...
        }
    }
    // ...
}

也许这会让它更清晰:

for(outerPair in map){
    val (innerPair, list) = outerPair
    val reservasNum = innerPair.first
    val reservasDay = innerPair.second
    val reservasCount = list.count()
    // ...
}

我故意保持这个功能(mapReservas)不受影响,因为也许你正在其他地方使用它。但是你可以使用Type aliases(从Kotlin 1.1开始)立即改进它。

typealias FlightNum = String
typealias Day = Int

fun mapReservas(reservas: List<Reservas>): 
                  Map<Pair<FlightNum, Day>, List<Reservas>>  {
   // ...
}

正如您所看到的,如果使用destructure语法和Type aliases,代码将变得更易读。