【问题标题】:Scala downwards or decreasing for loop?Scala向下或减少for循环?
【发布时间】:2011-02-06 17:35:24
【问题描述】:

在 Scala 中,您经常使用迭代器以递增顺序执行 for 循环,例如:

for(i <- 1 to 10){ code }

你会怎么做,让它从 10 变成 1?我猜10 to 1 给出了一个空迭代器(就像通常的范围数学一样)?

我制作了一个 Scala 脚本,它通过在迭代器上调用 reverse 来解决它,但在我看来这并不好,下面是要走的路吗?

def nBeers(n:Int) = n match {

    case 0 => ("No more bottles of beer on the wall, no more bottles of beer." +
               "\nGo to the store and buy some more, " +
               "99 bottles of beer on the wall.\n")

    case _ => (n + " bottles of beer on the wall, " + n +
               " bottles of beer.\n" +
               "Take one down and pass it around, " +
              (if((n-1)==0)
                   "no more"
               else
                   (n-1)) +
                   " bottles of beer on the wall.\n")
}

for(b <- (0 to 99).reverse)
    println(nBeers(b))

【问题讨论】:

    标签: scala iterator loops for-loop


    【解决方案1】:
    scala> 10 to 1 by -1
    res1: scala.collection.immutable.Range = Range(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
    

    【讨论】:

    • @Felix:不客气。我还应该指出,您还可以使用 until 代替 to 从范围中排除右侧端点。始终包含左侧端点。
    • 我已经知道 until,until 也是 Integers 上的一个函数,但是,“by”必须是 range/iterator 上的一个函数,无论从“to”和“until”返回什么职能。无论如何谢谢:)
    • Randall 的回答是最好的,但我认为 Range.inclusive(10, 1, -1) 值得一提。
    【解决方案2】:

    @Randall 的回答非常好,但为了完整起见,我想添加几个变体:

    scala> for (i <- (1 to 10).reverse) {code} //Will count in reverse.
    
    scala> for (i <- 10 to(1,-1)) {code} //Same as with "by", just uglier.
    

    【讨论】:

    • +1 表示第一个,但第二个是邪恶的——比by 可读性差,并且在任何情况下都不应该使用 IMO
    • 第二个是邪恶的,但建立在可用的直觉上
    • 谢谢,reverse 非常适合独占开始和包容结束,例如1 until x reverse 而不是 x - 1 to 1 by -1。
    【解决方案3】:

    Scala 提供了许多方法来循环向下工作。

    第一种解决方案:使用“to”和“by”

    //It will print 10 to 0. Here by -1 means it will decremented by -1.     
    for(i <- 10 to 0 by -1){
        println(i)
    }
    

    第二个解决方案:使用“to”和“reverse”

    for(i <- (0 to 10).reverse){
        println(i)
    }
    

    第三种解决方案:仅使用“to”

    //Here (0,-1) means the loop will execute till value 0 and decremented by -1.
    for(i <- 10 to (0,-1)){
        println(i)
    }
    

    【讨论】:

      【解决方案4】:

      使用 Pascal 编程后,我觉得这个定义很好用:

      implicit class RichInt(val value: Int) extends AnyVal {
        def downto (n: Int) = value to n by -1
        def downtil (n: Int) = value until n by -1
      }
      

      这样使用:

      for (i <- 10 downto 0) println(i)
      

      【讨论】:

      • 感谢您的回答。我在使用此解决方案时遇到问题。这是我的堆栈跟踪:Error:(57, 17) value class may not be a member of another class implicit class RichInt(val value: Int) extends AnyVal { ^
      • 正如错误消息(不是堆栈跟踪)所暗示的,您不能在另一个类中定义值类。要么在它之外定义它,要么在一个对象中定义它,要么删除extends AnyVal 部分(这仅用于消除一些开销)。
      【解决方案5】:

      你可以使用 Range 类:

      val r1 = new Range(10, 0, -1)
      for {
        i <- r1
      } println(i)
      

      【讨论】:

        【解决方案6】:

        您可以使用: for (i &lt;- 0 to 10 reverse) println(i)

        【讨论】:

          【解决方案7】:
          for (i <- 10 to (0,-1))
          

          循环将一直执行到值 == 0,每次递减 -1。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-22
            • 2011-10-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-07-22
            相关资源
            最近更新 更多