Incrementing the for loop (loop variable) in scala by power of 5 -


i had asked question on javaranch, couldn't response there. posting here well:

i have particular requirement increment in loop variable done multiplying 5 after each iteration. in java implement way:

for(int i=1;i<100;i=i*5){} 

in scala trying following code-

var j=1 for(i<-1.to(100).by(scala.math.pow(5,j).toint)) {   println(i+" "+j)   j=j+1 } 

but printing following output: 1 1 6 2 11 3 16 4 21 5 26 6 31 7 36 8 .... ....

its incrementing 5 always. how got multiplying increment 5 instead of adding it.

let's first explain problem. code:

var j=1 for(i<-1.to(100).by(scala.math.pow(5,j).toint)) {   println(i+" "+j)   j=j+1 } 

is equivalent this:

var j = 1 val range: range = predef.intwrapper(1).to(100) val increment: int = scala.math.pow(5, j).toint val byrange: range = range.by(increment) byrange.foreach {   println(i+" "+j)   j=j+1 } 

so, time mutate j, increment , byrange have been computed. , range immutable object -- can't change it. if produced new ranges while did foreach, object doing foreach still same.

now, solution. put, range not adequate needs. want geometric progression, not arithmetic one. me (and pretty else answering, seems), natural solution use stream or iterator created iterate, computes next value based on previous one.

for(i <- iterator.iterate(1)(_ * 5) takewhile (_ < 100)) {   println(i) } 

edit: stream vs iterator

stream , iterator different data structures, share property of being non-strict. property enables iterate exist, since method creating infinite collection1, takewhile create new2 collection finite. let's see here:

val s1 = stream.iterate(1)(_ * 5) // s1 infinite val s2 = s1.takewhile(_ < 100)    // s2 finite val i1 = iterator.iterate(1)(_ * 5) // i1 infinite val i2 = i1.takewhile(_ < 100)      // i2 finite 

these infinite collections possible because collection not pre-computed. on list, elements inside list stored somewhere time list has been created. on above examples, however, first element of each collection known in advance. others computed if , when required.

as mentioned, though, these different collections in other respects. stream immutable data structure. instance, can print contents of s2 many times wish, , show same output every time. on other hand, iterator mutable data structure. once used value, value forever gone. print contents of i2 twice, , empty second time around:

scala> s2 foreach println 1 5 25  scala> s2 foreach println 1 5 25  scala> i2 foreach println 1 5 25  scala> i2 foreach println  scala>  

stream, on other hand, lazy collection. once value has been computed, stay computed, instead of being discarded or recomputed every time. see below 1 example of behavior in action:

scala>     val s2 = s1.takewhile(_ < 100)    // s2 finite s2: scala.collection.immutable.stream[int] = stream(1, ?)  scala> println(s2) stream(1, ?)  scala> s2 foreach println 1 5 25  scala> println(s2) stream(1, 5, 25) 

so stream can fill memory if 1 not careful, whereas iterator occupies constant space. on other hand, 1 can surprised iterator, because of side effects.

(1) matter of fact, iterator not collection @ all, though shares lot of methods provided collections. on other hand, problem description gave, not interested in having collection of numbers, in iterating through them.

(2) actually, though takewhile create new iterator on scala 2.8.0, new iterator still linked old one, , changes in 1 have side effects on other. subject discussion, , might end being independent in future.


Comments

Popular posts from this blog

android - Spacing between the stars of a rating bar? -

aspxgridview - Devexpress grid - header filter does not work if column is initially hidden -

c# - How to execute a particular part of code asynchronously in a class -