【问题标题】:Change for loop index in Kotlin更改 Kotlin 中的循环索引
【发布时间】:2018-01-26 09:40:42
【问题描述】:

如何在 Kotlin 中修改循环变量?

对于我的特殊情况,我有一个 for 循环,在该循环中,对于某些条件,我想跳过下一次迭代:

for(i in 0..n) {
  // ...
  if(someCond) {
    i++ // Skip the next iteration
  }
}

但是,当我尝试这个时,我被告知“无法重新分配 val”。

【问题讨论】:

    标签: loops for-loop kotlin


    【解决方案1】:

    你不能改变当前元素,你需要使用 while 循环来代替:

    var i = 0
    while (i <= n) {
        // do something        
        
        if (someCond) {
            i++ // Skip the next iteration
        }
    
        i++
    }
    

    你想做什么?有可能有更惯用的方法来做到这一点。

    如果您可以重构此逻辑以跳过当前迭代,为什么不使用continue

    for (i in 0..n) {
        if (someCond) {
            continue
        }
        // ...
    }
    

    旁注:.. 范围包括在内,因此循环例如n 的大小列表,您通常需要 0..(n - 1),使用 until 更简单:0 until n


    在您的具体情况下,您可以使用windowed(Kotlin 1.2):

    list.asSequence().filter { someCond }.windowed(2, 1, false).forEach { 
        val (first, second) = it
        // ...
    }
    

    asSequence 会将列表转换为Sequence,从而消除filterwindowed 创建新List 的开销(因为它们现在都将返回Sequences)。

    如果您希望下一对不包含前一对的最后一个元素,请改用windowed(2, 2, false)

    【讨论】:

    • 手头的任务涉及迭代相邻的元素对......所以循环使用索引 i 和 i+1 一起工作。如果我发现有关 i+1 的内容意味着不应该再查看它,就会发生这种情况。
    • 我可能会建议您的 while 循环可以通过将 i 初始化为 -1 并设置条件 (++i
    • @Kricket 我添加了一种可能适合您尝试的方法
    • 不完全是。这样做会遍历对 (0,1)、(2,3) 等,但它永远不会与对 (1,2) 一起工作。
    • 我必须说,他们让这变得不必要地复杂了。 Imo 是 Kotlin 倒退而不是进化的少数几个领域之一。
    【解决方案2】:

    看起来您真正想做的是在列表上迭代大小为 2 的滑动窗口。如果您使用的是 kotlin 1.2 或更高版本,则可以使用 List.windowed() 库函数。

    例如,要考虑每对相邻元素,但丢弃其中第二个为负数的元素,您会这样做:

    val list = listOf(1, 2, 3, -4, -5, 6)
    list.windowed(2,1).filter { it[1] > 0 }.apply(::println)
    

    会打印出来的

    [[1, 2], [2, 3], [-5, 6]]
    

    跳过了 [3, -4] 和 [-4, -5] 对

    【讨论】:

      【解决方案3】:

      虽然很多人描述了这个问题并提出了一个我认为不适合初学者的高级方法或运算符的解决方案。 我对代码进行了修复,以便您可以轻松理解它,它只是使用 while 循环而不是 for 循环。如果您能理解并发现它有用,请考虑接受答案

      fun main(args:Array<String>){
      
          var alphabet = mutableListOf(
                  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
                  'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
          )
          var key = "keyword"
          println(key)
          for (i in key.indices)
          {
              var j = 0
              while (j < alphabet.size) {
                  if (key[i] == alphabet[j]){
                      alphabet.removeAt(j)     // 1. this line have error
                  } else j++
              }
          }
          print(alphabet)
      }
      

      【讨论】:

        【解决方案4】:

        请试试这个方法,

        for ((position, item) in list.withIndex()){
        }
        

        在这里你会得到位置和对象。

        【讨论】:

          猜你喜欢
          • 2011-02-19
          • 2015-07-17
          • 2020-12-11
          • 2013-01-24
          • 2013-06-03
          • 2023-04-05
          • 1970-01-01
          • 2016-03-10
          • 1970-01-01
          相关资源
          最近更新 更多