3

I have the following block of code and want to reduce it using Kotlin. How can I do that?

if (name == nameArray[0]) {
    // The statement
} else if(name == nameArray[1]) {
    // The statement
} else if(name == nameArray[2]) {
    // The statement
} else if(name == nameArray[3]) {
    // The statement
} else {
    // The statement
}
deHaar
  • 17,687
  • 10
  • 38
  • 51
sadankhan
  • 45
  • 5

5 Answers5

5

If the array is small and you want to map an action to each index:

You could use indexOfFirst to determine the smallest index which meats your condition. Then you can use a when statement to decide what to do.

when(nameArray.indexOfFirst{ it == name }) {
    0 -> // do something
    1 -> // do something else
    //...
    else -> // do something different
}

In case you might want to do the same thing for multiple indices you can use comma separated values. In case the indices are consecutive, you can use ranges:

when(nameArray.indexOfFirst{ it == name }) {
    0 -> // do something
    1, 2 -> // do the same thing for 1 and 2
    in 3..6 -> // do the same thing for 3, 4, 5 and 6
    //...
    else -> // do something different
}

In order to use this syntax it is a good idea to do index retrieval (like shown) first.

If the array is big and you really only want to check for specific elements:

when(name) {
    nameArray[0] -> // do something
    nameArray[1] -> // do something
    nameArray[2] -> // do something
    nameArray[3] -> // do something
    else -> // other action
}
Madhu Bhat
  • 13,559
  • 2
  • 38
  • 54
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
  • in the worst case (say array has million items, and matching item is last one) `nameArray.indexOfFirst{ it == name }` ***will cost you lot more than 3, 4 simple comparisons as in the question*** – mightyWOZ Jan 29 '20 at 15:16
  • @mightyWOZ true, but then it wouldn't be feasible to list an action for each of those cases (using `when` what you seemed to have suggested) either. the answer was tailored to the question and its use-case. it was meant to be short and concise. – Willi Mentzel Jan 29 '20 at 15:37
  • First, question doesn't say anything about the size of array. ***(can be 5 or 5000000)*** second, ***question only deals with five cases irrespective of the size of the array, which can be handled very easily by when*** – mightyWOZ Jan 29 '20 at 15:44
  • @mightyWOZ ok, I see your point. I was thinking that OP wants to cover all cases of the array (because it starts with zero and has consecutive indices) (which then would mean that it can't be that big). still if the array is not large, I would most likely go with what I suggested, especially because of the second part of the answer. anyway thank you for your remark. – Willi Mentzel Jan 29 '20 at 16:00
2

You can use when to simplify it as below

when(name) {
    nameArray[0] -> //statement
    nameArray[1] -> //statement
    nameArray[2] -> //statement
    nameArray[3] -> //statement
    else -> //statement
}

Alternatively, if you can use an enum instead of the nameArray as below

enum class Names {
    NAME_1, NAME_2, NAME_3
}

And have name of the Names enum type, you can then use the when clause as below, which is a cleaner way and is more readable

when(name) {
    Names.NAME_1 -> //statement
    Names.NAME_2 -> //statement
    Names.NAME_3 -> //statement
}
Madhu Bhat
  • 13,559
  • 2
  • 38
  • 54
1

You can use a better and more powerful Kotlin construct, when.

It works similarly to switch-case constructs but you can use expression too, check here for more.

Specific to your example you may write:

when (name) {
    nameArray[0] -> {
    //The statement
    }
    nameArray[1] -> {
    //The statement
    }
    nameArray[2] -> {
    //The statement
    }
    nameArray[3] -> {
    //The statement
    }
    else -> { 
    //Executes when conditions are not met
    }
}
Andrea Nisticò
  • 466
  • 2
  • 4
  • 11
1

Maybe I'm misinterpreting what you want to do, but in my opinion a when statement is over-complicating this. In your original code you just want to determine if the array contains the name value in any of the indices from 0 to 3 and respond accordingly.

if ((nameArray.indexOfFirst(name::equals) in 0..3) { 
    // The statement
} else {
    // The else branch
}
Tenfour04
  • 83,111
  • 11
  • 94
  • 154
0

Shorter way: Iterate the array instead of if-else every possible index of the array:

fun main(args: Array<String>) {
    val nameArray: Array<String> = arrayOf("naam", "nombre", "name", "Name")
    val name: String = "name";

    for (i in 0..(nameArray.size - 1)) {
        if (name == nameArray[i]) {
            println("The statement should be executed on index " + i)
        }
    }
}

Output:

The statement should be executed on index 2
deHaar
  • 17,687
  • 10
  • 38
  • 51