Reputation: 6582
I have a function f(a: A): A
and an integer N
. I'd like to write a function that will return the following Vector[A]:
Vector(a, f(a), f(f(a)), f(f(f(a))), ..., f^{N}(a))
where f^{N}
denotes applying f
recursively N
times. N
may be relatively large. I am looking for a solution that will not require reversing a data structure or traversing it more than once. Clearly, there are many ways to do this; I am looking for functional, idiomatic and readable code.
Upvotes: 0
Views: 329
Reputation: 18859
{Vector, List, Array, ...}.iterator
def iterate[A](start: A, len: Int)(f: (A) ⇒ A): Vector[A]
Produces a collection containing repeated applications of a function to a start value. start the start value of the collection len the number of elements contained inthe collection f the function that's repeatedly applied returns a collection with len values in the sequence start, f(start), f(f(start)), ...
scala> def f(x: Int): Int = if(x%2 == 0) x/2 else 3*x+1
f: (x: Int)Int
scala> Vector.iterate(10000, 10)(f)
res0: scala.collection.immutable.Vector[Int] =
Vector(10000, 5000, 2500, 1250, 625, 1876, 938, 469, 1408, 704)
Or if you really want to implement it yourself, here is a possible solution
scala> def iterator[A](start: A, len: Int)(f: A => A): Vector[A] = len match {
| case 0 => Vector()
| case _ => start +: iterator(f(start), len-1)(f)
| }
iterator: [A](start: A, len: Int)(f: A => A)Vector[A]
scala> iterator(10000, 100)(f)
res1: Vector[Int] = Vector(10000, 5000, 2500, 1250, 625, 1876, 938, 469, 1408,
704, 352, 176, 88, 44, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2,
1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2,
1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2,
1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4)
Upvotes: 5