Scala ลงหรือลดลงสำหรับลูป?


115

ใน Scala คุณมักใช้ตัววนซ้ำเพื่อทำforวนซ้ำตามลำดับที่เพิ่มขึ้นเช่น:

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

คุณจะทำอย่างไรให้มันเปลี่ยนจาก 10 เป็น 1 ฉันเดาว่า10 to 1ให้ตัววนซ้ำว่าง (เหมือนคณิตศาสตร์พิสัยปกติ)?

ฉันสร้างสคริปต์ Scala ซึ่งแก้ไขได้โดยการเรียก reverse บน iterator แต่มันไม่ดีในความคิดของฉันวิธีต่อไปนี้จะไปหรือไม่?

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

คำตอบ:


229
scala> 10 to 1 by -1
res1: scala.collection.immutable.Range = Range(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)

2
@ เฟลิกซ์: ยินดีต้อนรับ ฉันควรจะชี้ให้เห็นuntilด้วยว่าคุณสามารถใช้toแทนจุดปลายด้านขวามือออกจากช่วงได้ จุดสิ้นสุดทางซ้ายมือจะรวมอยู่ด้วยเสมอ
Randall Schulz

ฉันรู้แล้วเกี่ยวกับ until, until เป็นฟังก์ชันบนจำนวนเต็มด้วยอย่างไรก็ตาม "โดย" ต้องเป็นฟังก์ชันบน range / iterator สิ่งที่ส่งกลับจากฟังก์ชัน "ถึง" และ "ถึง" ขอบคุณต่อไป :)
เฟลิกซ์

5
คำตอบของ Randall ดีที่สุด แต่ฉันคิดว่าRange.inclusive(10, 1, -1)สมควรได้รับการกล่าวถึง
john sullivan

37

คำตอบจาก @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.

9
+1 สำหรับอันแรก แต่อันที่สองนั้นชั่วร้าย - อ่านได้น้อยกว่าbyและไม่ควรใช้ IMO ในทุกกรณี
om-nom-nom

4
สิ่งที่สองคือความชั่วร้าย แต่สร้างสัญชาตญาณในสิ่งที่มีอยู่
Zaheer

10

Scala มีหลายวิธีในการทำงานแบบวนลง

โซลูชันที่ 1: ด้วย "ถึง" และ "โดย"

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

แนวทางที่ 2: ด้วย "ถึง" และ "ย้อนกลับ"

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

แนวทางที่ 3: ด้วย "ถึง" เท่านั้น

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

6

หลังจากตั้งโปรแกรมในภาษาปาสคาลฉันพบว่าคำจำกัดความนี้ดีที่จะใช้:

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)

ขอบคุณสำหรับคำตอบ ฉันมีปัญหาในการใช้โซลูชันนี้ นี่คือ stacktrace ของฉัน:Error:(57, 17) value class may not be a member of another class implicit class RichInt(val value: Int) extends AnyVal { ^
เบิร์ต

ตามที่ข้อความแสดงข้อผิดพลาด (ไม่ใช่การติดตามสแต็ก) แนะนำคุณไม่สามารถกำหนดคลาสค่าภายในคลาสอื่นได้ กำหนดไว้ด้านนอก oike ในวัตถุหรือลบextends AnyValส่วน (ซึ่งทำหน้าที่ลบค่าใช้จ่ายบางส่วนเท่านั้น)
LP_



0
for (i <- 10 to (0,-1))

ลูปจะดำเนินการจนถึงค่า == 0 ลดลงทุกครั้งที่ -1

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.