Aşağı doğru ölçekleme veya döngü için azalma?


115

Scala'da, aşağıdaki forgibi artan bir sırayla döngü yapmak için genellikle bir yineleyici kullanırsınız :

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

10'dan 1'e çıkması için nasıl yaparsınız? Sanırım 10 to 1boş bir yineleyici veriyor (normal aralık matematiği gibi)?

Yineleyicide ters çağırarak sorunu çözen bir Scala betiği yaptım ama bence bu hoş değil, aşağıdaki yol mu?

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

Yanıtlar:


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

2
@Felix: Rica ederim. Ayrıca , sağ taraftaki uç noktayı aralıktan hariç tutmak için untilyerine kullanabileceğinizi de belirtmeliydim to. Sol taraftaki uç nokta her zaman dahil edilir.
Randall Schulz

Tane hakkında zaten biliyordum, until de Tamsayılar üzerinde bir işlev, ancak "by", "to" ve "until" işlevlerinden döndürülen her ne olursa olsun, aralık / yineleyicide bir işlev olmalıdır. Yine de teşekkürler :)
Felix

5
Randall'ın cevabı en iyisidir, ancak bence Range.inclusive(10, 1, -1)bahsetmeyi hak ediyor.
john Sullivan

37

@Randall'ın cevabı altın kadar iyi, ancak tamamlama adına birkaç varyasyon eklemek istedim:

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
Birincisi için +1, ancak ikincisi kötü - daha az okunabilir byve IMO hiçbir koşulda kullanılmamalıdır
om-nom-nom

4
İkincisi kötü ama mevcut olanın üzerine sezgi geliştiriyor
Zaheer

10

Scala, döngüde aşağı doğru çalışmak için birçok yol sağlar.

1. Çözüm: "to" ve "by" ile

//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. Çözüm: "-" ve "ters" ile

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

3. Çözüm: yalnızca "to" ile

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

6

Pascal'da programladıktan sonra, bu tanımı kullanmayı güzel buluyorum:

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
}

Bu şekilde kullanılır:

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

Cevabınız için teşekkür ederim. Bu çözümü kullanırken sorun yaşıyorum. İşte yığın izlemem:Error:(57, 17) value class may not be a member of another class implicit class RichInt(val value: Int) extends AnyVal { ^
robert

Hata mesajının (yığın izleme değil) gösterdiği gibi, başka bir sınıfın içindeki değer sınıfını tanımlayamazsınız. Ya onun dışında tanımlayın, bir nesneye benzeyin ya da extends AnyValparçayı çıkarın (bu sadece bazı ek yükleri kaldırmaya yarar).
LP_

1

Range sınıfını kullanabilirsiniz:

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

1

Kullanabilirsiniz : for (i <- 0 to 10 reverse) println(i)


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

Döngü, == 0 değeri her seferinde -1 azalana kadar çalışacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.