【问题标题】:how to change nested if-else to when statements using Kotlin?如何使用 Kotlin 将嵌套的 if-else 更改为 when 语句?
【发布时间】:2020-05-15 00:56:57
【问题描述】:

我有以下代码块,并希望使用 Kotlin 减少它。我该怎么做?

if (name == nameArray[0]) {
    // The statement
} else if(name == nameArray[1]) {
    // The statement
} else if(name == nameArray[2]) {
    // The statement
} else if(name == nameArray[3]) {
    // The statement
} else {
    // The statement
}

【问题讨论】:

  • 你真的检查了数组中的同一个索引 3 次还是一个错字?
  • 这里嵌套了什么?
  • 好的,现在修好了。
  • 这能回答你的问题吗? How to Implement switch case in Kotlin
  • 您可以反过来迭代nameArray,因为name 保持不变,不是吗?你能提供一个最小的例子和nameArray的确切类型吗?

标签: kotlin


【解决方案1】:

如果数组很小并且您想将一个动作映射到每个索引:

您可以使用indexOfFirst 来确定符合您条件的最小索引。然后您可以使用when 语句来决定要做什么。

when(nameArray.indexOfFirst{ it == name }) {
    0 -> // do something
    1 -> // do something else
    //...
    else -> // do something different
}

如果您可能想对多个索引执行相同的操作,您可以使用逗号分隔值。如果索引是连续的,您可以使用范围:

when(nameArray.indexOfFirst{ it == name }) {
    0 -> // do something
    1, 2 -> // do the same thing for 1 and 2
    in 3..6 -> // do the same thing for 3, 4, 5 and 6
    //...
    else -> // do something different
}

为了使用这种语法,最好先进行索引检索(如图所示)。

如果数组很大并且您真的只想检查特定元素:

when(name) {
    nameArray[0] -> // do something
    nameArray[1] -> // do something
    nameArray[2] -> // do something
    nameArray[3] -> // do something
    else -> // other action
}

【讨论】:

  • 在最坏的情况下(比如数组有百万个项目,匹配项目是最后一个)nameArray.indexOfFirst{ it == name } 将花费您超过 3、4 次简单比较,如问题
  • @mightyWOZ 是的,但是对于这些案例中的每一个都列出一个操作也不可行(使用您似乎建议的when)。答案是针对问题及其用例量身定制的。它旨在简短明了。
  • 首先,问题没有说明数组的大小。 (可以是5或者5000000) 其次,question只处理5种情况,与数组大小无关,可以很容易处理当
  • @mightyWOZ 好的,我明白你的意思。我在想 OP 想要覆盖数组的所有情况(因为它从零开始并且有连续的索引)(这意味着它不可能那么大)。如果数组不大,我很可能会按照我的建议去做,特别是因为答案的第二部分。无论如何,谢谢你的评论。
【解决方案2】:

您可以使用when 简化如下

when(name) {
    nameArray[0] -> //statement
    nameArray[1] -> //statement
    nameArray[2] -> //statement
    nameArray[3] -> //statement
    else -> //statement
}

或者,如果您可以使用枚举而不是 nameArray,如下所示

enum class Names {
    NAME_1, NAME_2, NAME_3
}

并且拥有Names枚举类型的name,然后您可以使用如下when子句,这是一种更简洁的方式并且更具可读性

when(name) {
    Names.NAME_1 -> //statement
    Names.NAME_2 -> //statement
    Names.NAME_3 -> //statement
}

【讨论】:

    【解决方案3】:

    您可以使用更好、更强大的 Kotlin 构造 when

    它的工作方式类似于 switch-case 构造,但您也可以使用表达式,请查看here 了解更多信息。

    具体到你可以写的例子:

    when (name) {
        nameArray[0] -> {
        //The statement
        }
        nameArray[1] -> {
        //The statement
        }
        nameArray[2] -> {
        //The statement
        }
        nameArray[3] -> {
        //The statement
        }
        else -> { 
        //Executes when conditions are not met
        }
    }
    

    【讨论】:

      【解决方案4】:

      也许我误解了你想要做什么,但在我看来,when 语句过于复杂了。在您的原始代码中,您只想确定数组是否包含从 0 到 3 的任何索引中的 name 值并做出相应的响应。

      if ((nameArray.indexOfFirst(name::equals) in 0..3) { 
          // The statement
      } else {
          // The else branch
      }
      

      【讨论】:

      • 从问题中看不太清楚,但他可能想为不同的索引做不同的事情。
      【解决方案5】:

      更短的方法:迭代数组而不是 if-else 数组的每个可能索引:

      fun main(args: Array<String>) {
          val nameArray: Array<String> = arrayOf("naam", "nombre", "name", "Name")
          val name: String = "name";
      
          for (i in 0..(nameArray.size - 1)) {
              if (name == nameArray[i]) {
                  println("The statement should be executed on index " + i)
              }
          }
      }
      

      输出:

      The statement should be executed on index 2
      

      【讨论】:

      • 您可以使用i in 0 until nameArray 代替0..(nameArray.size - 1),它不会更短,但可能更易于阅读:)
      • @WilliMentzel nameArray.indices 怎么样?
      • @xinaiz 或者更好的forEachIndexed :)
      • @WilliMentzel 也可以使用iterator.withIndex()... Kotlin 有很多可能性 ;-) 我承认它们中的大多数比我的示例更具可读性...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多