From Java to Kotlin, first impression on for loops
Tags: java, kotlin, webdev, beginners
Published: 2023-05-26 05:49:13

What? This was supposed to be like Java? I can't even write a for loop?!

Or, at least, that was my first impression of Kotlin. 
I tried to write `for (int i = 0...)` but then I quickly adapted to `for (var i = 0...)` and then `for (var i = 0 : Int....)` but realised that I was going nowhere. 

After scratching my noggin and saying a few ~~curses~~ self-encouraging words. I opted in for the regular enhanced for loop instead. But alas `for (n : ints)` also resulted in a compilation error. 

So lets dive in to what I _should_ have done. 

Quick disclaimer is that the `IntRange` object, as well as the other ranges in the `kotlin.ranges` package are easy, and often used in, for instance, loops. They can be easily created like the following examples: 

```kotlin
val intRange = (1 .. 5)
val theEntireEnglishAlphabet = ('a' .. 'z')

// The ".." operator makes it an ascending range. 
// Another option, is to use the until or downTo keywords

val theSameAsIntRange = (1 until 5)
val descendingIntRange = (5 downTo 1)
```

So, back to what this article is all about, how do I use for loops? 

Here are some examples! 

```kotlin
// the regular, wonderful, enhanced for-loop

val someArr = intArrayOf(5, 3, 6, 32, 20, 1)

fun enhancedLoop() {
  for (num in someArr) {
    println(num) // -> console: 5, 3, 6, 32, 20, 1
  } 
}
```

Yes! A loop! :raised_hands: But how do I get the indexes? :thinking: 
There are 2 ways of easily achieving this. One using the `.indicies` property(?) that you'll find on all of the Arrays and Collections that returns a... you guessed it! `IntRange`.

```kotlin

// using the .indicies 

val someArr = intArrayOf(5, 3, 6, 32, 20, 1)

fun loopWithIndex() {
  for (i in someArr.indicies) {
    println(i) // -> 0, 1, 2, 3, 4, 5
  }
}

// and if you're looking to loop until a certain value.
// you can just create a new range

// top level: private const val MAX_LOOPS = 5 

fun loopWithInlineRange() {
  for (i in 0 .. MAX_LOOPS) { // you can also use the "until" keyword for increased readability 
    println(i) // -> 0, 1, 2, 3, 4, 5
  }
}

// and if you'd like to do it descending, most likely just 
// a "backwards loop" 

val someOtherArr = intArrayOf(1, 2, 10, 4, 5)

fun loopDescendingWithRange(){
  for (i in someOtherArr.size -1 downTo 0){
    println(someOtherArr[i]) // -> 5, 4, 10 2, 1
  }
}

```

"Nice! But that `-1` feels very caveCode for being such a new language. Can't I just deconstruct the value and the index and keep it enhanced and safe from `IndexOutOfBoundsExceptions`?" you ask yourself. 

Yes! Is the answer. By using the method `withIndex()` that you'll find on your arrays! 

```kotlin

val someArr = intArrayOf(5, 3, 6, 32, 20, 1)

for ((i, num) in someArr.withIndex()) {
  println("$num has index $i") // -> "5 has index 0", "3 has index 1" .... 
}

// Important to note is that you're getting the index first, then the value

// If you want it reversed, you can just reverse the arr

for ((i, num) in someArr.reversed().withIndex()) {
  println("$num has index $i") // -> "1 has index 5", "20 has index 4" .... 
}

```

I hope you found this little read helpful. I missed my good 'ol `for (int i = 0; i < whatHaveYou.length(); i++)` in the beginning, but rather quickly grew fond of the usage of ranges instead.