在scala中以5的幂递增for循环(循环变量)
我曾在
Javaranch问过这个问题,但在那里得不到答复.所以在这里发布它:
我有这个特殊要求,其中循环变量的增量是通过在每次迭代后将它乘以5来完成的.在Java中,我们可以这样实现它: for(int i=1;i<100;i=i*5){} 在scala我尝试以下代码 – var j=1 for(i<-1.to(100).by(scala.math.pow(5,j).toInt)) { println(i+" "+j) j=j+1 } 但它的打印输出如下: 它总是递增5.那么我如何实际将增量乘以5而不是添加它. 解决方法
我们先解释一下这个问题.这段代码:
var j=1 for(i<-1.to(100).by(scala.math.pow(5,j).toInt)) { println(i+" "+j) j=j+1 } 相当于: 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 } 因此,当你变异j时,已经计算了increment和byRange.而Range是一个不可变的对象 – 你无法改变它.即使你在做foreach时产生了新的范围,做foreach的对象仍然是相同的. 现在,到解决方案.简而言之,Range不足以满足您的需求.你想要几何级数,而不是算术级数.对我来说(似乎其他所有人都在回答),自然的解决方案是使用使用iterate创建的Stream或Iterator,它根据前一个值计算下一个值. for(i <- Iterator.iterate(1)(_ * 5) takeWhile (_ < 100)) { println(i) } 编辑:关于Stream vs Iterator Stream和Iterator是非常不同的数据结构,它们共享非严格的属性.这个属性使迭代甚至存在,因为这个方法创建了一个无限集合1,takeWhile将从中创建一个有限的new2集合.我们来看看: val s1 = Stream.iterate(1)(_ * 5) // s1 is infinite val s2 = s1.takeWhile(_ < 100) // s2 is finite val i1 = Iterator.iterate(1)(_ * 5) // i1 is infinite val i2 = i1.takeWhile(_ < 100) // i2 is finite 这些无限集合是可能的,因为集合不是预先计算的.在列表中,列表中的所有元素实际上都是在创建列表时存储在某处.然而,在上面的例子中,只预先知道每个集合的第一个元素.只有在需要时才会计算所有其他数据. 正如我所提到的,这些在其他方面是非常不同的集合. Stream是一种不可变的数据结构.例如,您可以根据需要多次打印s2的内容,并且每次都会显示相同的输出.另一方面,Iterator是一个可变数据结构.一旦你使用了一个值,那个价值就永远消失了.打印i2的内容两次,第二次打印为空: 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是一个懒惰的集合.一旦计算了一个值,它就会保持计算,而不是每次都被丢弃或重新计算.请参阅下面的行为中的一个示例: scala> val s2 = s1.takeWhile(_ < 100) // s2 is 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) 因此,如果不小心,Stream实际上可以填满内存,而Iterator占用恒定的空间.另一方面,Iterator会因为它的副作用而感到惊讶. (1)事实上,Iterator根本不是一个集合,尽管它分享了很多集合提供的方法.另一方面,从您给出的问题描述中,您并不真正感兴趣的是拥有一组数字,只是在迭代它们. (2)实际上,虽然takeWhile会在Scala 2.8.0上创建一个新的Iterator,但是这个新的迭代器仍然会链接到旧的迭代器,而其中一个的变化会对另一个产生副作用.这需要讨论,它们最终可能在未来真正独立. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |