Learning Kotlin: The For Loop

Submitted by Robert MacLean on Wed, 08/15/2018 - 09:00
**More Information** * This is the 20th post in a multipart series. If you want to read more, see our [series index](/learning-kotlin-introduction) Kotlin has two loops, `while` and `for`. When I started I was like, "yup, I know those..." - except I didn't. `while` works the way I expected it would but `for` it is something else. First Kotlin does not have a traditional `for` loop, eg `for (var i =0;i< max; i++)`... the `for` loop in Kotlin is closer to the iterator `foreach` loop in C#. ## Basic Let's start with the basics, how do I run a loop, say 10 times where we print out `0, 1, 2, 3, 4, 5, 6, 7, 8, 9`: fun main(args:Array<String>) {     for(i in 0..9) {         println(i)     } } In this, we use a [ClosedRange](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.ranges/-closed-range/index.html) (0..9) to state the start and end of the loop. This would be the same as `for (var i=0; i< 10; i++)`. Now, normally we want to loop over an array of items, so we can do this in two ways. First the equivalent of the C# for iterator/JS `for of`: fun main(args:Array<String>) {     val a = arrayOf("The","Quick","Brown","Fox")     for(i in a) {         println(i)     } } and if we do the older style of using a normal `for` loop and using the index we have: fun main(args:Array<String>) {     val a = arrayOf("The","Quick","Brown","Fox")     for(i in 0 until a.size) {         val value = a[i]         println(value)     } } What is awesome in the above is the Range, rather than having the _inclusive_ lower and _inclusive_ upper bounds of the `..` range we using the keyword `until` which gives us an _exclusive_ upper bound. Kotlin is all about helpers, and last time we looked at [destructuring](/learning-kotlin-destructuring) so it shouldn't be a surprise we can use that to have BOTH the index and the value in the `for` loop. fun main(args:Array<String>) {     val a = arrayOf("The","Quick","Brown","Fox")     for((i, value) in a.withIndex()) {         println("$i is $value")     } } ## Extras The `for` loop has two additional options worth knowing; the first is `downTo` which loops from largest to smallest. This example which print `4321`): for (i in 4 downTo 1) print(i) The second is `step` which allows you to control how many steps to take when moving to the next item, for this example we will get `42`: for (i in 4 downTo 1 step 2) print(i) ## Operator Adding support for this to our own classes is trivial, we merely need to add the interface `Iterator` to our class. This adds two methods, ` fun next():T` which should return the next value in the collection and `fun hasNext():Boolean` which should return true if there is another value available. Let us look at doing this with a class of prime numbers but for our example, we will add one condition since there are infinite primes we will have a top bound so it eventually ends - this is stored in the `maxToHunt` variable. In the code our `next` function not only returns the next value, it calculates the NEXT NEXT value too which lets us set if there are more primes left if `next` is called again. class PrimeNumbers : Iterator<Int> {     var currentPrime = 1;     val maxToHunt = 100;     var morePrimesToFind = true;       override fun next():Int {         val result = this.currentPrime;           this.currentPrime += 1;         while(this.currentPrime < this.maxToHunt) {             var primeFound = true             for(divisor in this.currentPrime-1 downTo 2) {                   if (this.currentPrime % divisor == 0) {                     this.currentPrime += 1                     primeFound = false                     break                 }             }               if (primeFound) {                 break             }         }           this.morePrimesToFind = this.currentPrime < this.maxToHunt         return result     }       override fun hasNext() = this.morePrimesToFind }   fun main(args:Array<String>) {     for (i in PrimeNumbers()) {         println("$i is prime")     } }