Home > Mobile >  How to produce a true `Iterator[Long]` in Scala
How to produce a true `Iterator[Long]` in Scala

Time:07-11

I came across this other post looking for a way to create an Iterator[Long].

Currently the Scala SDK does not have any Iterator constructor that produces an Iterator[Long].

Other collection types may (unverified) provide some kind of constructor, yielding a value from which a call to .iterator may produce a Iterator[Long], but how can you guarantee the 'lazy and forgetful' semantics of an Iterator?

CodePudding user response:

Something like this lets you iterate through all (positive) Longs sequentially:

Iterator.iterate(1L)(_   1)

Alternatively, this produces an infinite iterator of random Longs:

Iterator.continually(util.Random.nextLong) 

This generates an infinite sequence of Fibonacci numbers:

Iterator.iterate(1L -> 1L) { case (a,b) => (b, a b) }.map(_._1)

CodePudding user response:

Probably in most cases Iterator.from(<Int>).map(_.toLong) would suffice, but this will wrap at Int.MaxValue;
if you are testing an API that truly handles Longs and you want coverage extending over the domain of numbers greater than Int.MaxValue, then this is clearly inadequate.

Unfold to the rescue:

package code

object Code {
  implicit class IteratorFromLongOps(val obj: Iterator.type) extends AnyVal {
    def from(start: Long): Iterator[Long] = Iterator.unfold(start)(s => Some((s, s 1)))
  }
}
scala> import code.Code._
import code.Code._

scala> Iterator.from(Int.MaxValue - 1).take(4).foreach(println)
2147483646
2147483647
-2147483648
-2147483647

scala> Iterator.from((Int.MaxValue - 1).toLong).take(4).foreach(println)
2147483646
2147483647
2147483648
2147483649
  • Related