Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case Sensitivity Kotlin / ignoreCase

I am trying to ignore case sensitivity on a string. For example, a user can put "Brazil" or "brasil" and the fun will trigger. How do I implement this? I am new to Kotlin.

fun questionFour() {
    val edittextCountry = findViewById<EditText>(R.id.editTextCountry)
    val answerEditText = edittextCountry.getText().toString()

    if (answerEditText == "Brazil") {
        correctAnswers++
    }

    if (answerEditText == "Brasil") {
        correctAnswers++
    }
}

EDIT

Another person helped me write like this. My question now about this way is "Is there a cleaner way to write this?"

fun questionFour() {
    val edittextCountry = findViewById<EditText>(R.id.editTextCountry)
    val answerEditText = edittextCountry.getText().toString()

    if (answerEditText.toLowerCase() == "Brazil".toLowerCase() || answerEditText.toLowerCase() == "Brasil".toLowerCase()) {
        correctAnswers++
    }
}

Answer

fun questionFour() {

        val edittextCountry = findViewById<EditText>(R.id.editTextCountry)
        val answerEditText = edittextCountry.getText().toString()

        if (answerEditText.equals("brasil", ignoreCase = true) || answerEditText.equals("brazil", ignoreCase = true)) {
            correctAnswers++
        }
    }
like image 979
superheron Avatar asked Mar 18 '18 15:03

superheron


3 Answers

You can call the equals function directly, which will allow you to specify the optional parameter ignoreCase:

if (answerEditText.equals("brasil", ignoreCase = true)) {
    correctAnswers++
}
like image 199
Shadowfacts Avatar answered Nov 13 '22 01:11

Shadowfacts


The core problem is that == just calls through to equals(), which is case sensitive. There are a few ways to solve this:

1) Lowercase the input and direct compare:

if (answerEditText.toLowerCase() == "brasil" ||
    answerEditText.toLowerCase() == "brazil") {
    // Do something
}

This is easy to understand and maintain, but if you have more than a couple of answers, it gets unwieldy.

2) Lowercase the input and test for values in a set:

if (answerEditText.toLowerCase() in setOf("brasil", "brazil")) {
    // Do Something
}

Perhaps define the set as a constant somewhere (in a companion object?) to avoid recreating it a few times. This is nice and clear, useful when you have a lot of answers.

3) Ignore the case and compare via .equals() method:

if (answerEditText.equals("Brazil", true) ||
    answerEditText.equals("Brasil", true)) {
    // Do something
}

Similar to option 1, useful when you only have a coupe of answers to deal with.

4) Use a case insensitive regular expression:

val answer = "^Bra(s|z)il$".toRegex(RegexOption.IGNORE_CASE)
if (answer.matches(answerEditText)) {
    // Do something
}

Again, create the answer regex once and store it somewhere to avoid recreating. I feel this is an overkill solution.

like image 7
Todd Avatar answered Nov 13 '22 02:11

Todd


We created extension function and use it so we can avoid specifying second parameter.

fun String.equalsIgnoreCase(other: String?): Boolean {
    if (other == null) {
        return false
    }

    return this.equals(other, true)
}

println("California".equalsIgnoreCase("CALIFORNIA"))
like image 1
metasync Avatar answered Nov 13 '22 00:11

metasync