Infinite streams in Scala

后端 未结 5 1610
忘了有多久
忘了有多久 2021-02-03 17:28

Say I have a function, for example the old favourite

def factorial(n:Int) = (BigInt(1) /: (1 to n)) (_*_)

Now I want to find the biggest value

5条回答
  •  Happy的楠姐
    2021-02-03 18:31

    A Solution Using Iterators

    You can also use an Iterator instead of a Stream. The Stream keeps references of all computed values. So if you plan to visit each value only once, an iterator is a more efficient approach. The downside of the iterator is its mutability, though.

    There are some nice convenience methods for creating Iterators defined on its companion object.

    Edit

    Unfortunately there's no short (library supported) way I know of to achieve something like

    Stream.from(1) takeWhile (factorial(_) <= Long.MaxValue) last
    

    The approach I take to advance an Iterator for a certain number of elements is drop(n: Int) or dropWhile:

    Iterator.from(1).dropWhile( factorial(_) <= Long.MaxValue).next - 1
    

    The - 1 works for this special purpose but is not a general solution. But it should be no problem to implement a last method on an Iterator using pimp my library. The problem is taking the last element of an infinite Iterator could be problematic. So it should be implemented as method like lastWith integrating the takeWhile.

    An ugly workaround can be done using sliding, which is implemented for Iterator:

    scala> Iterator.from(1).sliding(2).dropWhile(_.tail.head < 10).next.head
    res12: Int = 9
    

提交回复
热议问题