Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to simplify when expression in kotlin

I’d like to simplify this expression, especially "isDigit" and "isLetter" case. How to do it?

smoothInput.forEach { char ->
            when {
                char.isValidOperator() -> {
                    output.push(char)
                }

                char.isDigit() -> {
                    if (output.isNotEmpty() && output.last()!!.isNumeric()) output.addToLast(char)
                    else output.push(char)
                }

                char.isLetter() -> {
                    if (output.isNotEmpty() && output.last()!!.isValidVariableName()) output.addToLast(char)
                    else output.push(char)
                }

                else -> {
                    throw InvalidIdentifierException()
                }
            }
        }

I think, that it isn’t important, but it’s much better to add code here than in comment
output is InputStack Type:

class InputStack : Stack<String> {

    override val storage = mutableListOf<String>()
    fun push(e: Char) = push(e.toString())
    fun push(e: Operator) = push(e.toString())

    fun addToLast(e: Char) {
        storage[storage.size - 1] += e.toString()
    }
}

Stack Interface:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

interface Stack<T> {
    val storage: MutableList<T>
    fun asString(): String = buildString {
        appendLine("----top----")
        storage.asReversed().forEach {
            appendLine(it)
        }
        appendLine("-----------")
    }

    fun push(element: T) = storage.add(element)
    fun pop(): T {
        if (storage.size == 0) throw EmptyStackException()
        return storage.removeAt(storage.size - 1)
    }

    fun isEmpty(): Boolean = storage.isEmpty()
    fun isNotEmpty(): Boolean = !isEmpty()
    fun last(): T? = storage.lastOrNull()
    fun forEach(action: (T) -> Unit) {
        for (element in storage) action(element)
    }
}

>Solution :

You can extract some common parts in the following way:

fun addCharToOutputConditionally(char: Char, output: InputStack, conditionOnLast: (String) -> Boolean) {
    if (output.isNotEmpty() && conditionOnLast(output.last()!!)) output.addToLast(char)
    else output.push(char)
}

smoothInput.forEach { char ->
    when {
        char.isValidOperator() -> {
            output.push(char)
        }

        char.isDigit() -> {
            addCharToOutputConditionally(char, output) {
                it.isNumeric()
            }
        }

        char.isLetter() -> {
            addCharToOutputConditionally(char, output) {
                it.isValidVariableName()
            }
        }

        else -> {
            throw InvalidIdentifierException()
        }
    }
}

However, in cases like this, I don’t think it’s usually worth spending the time to refactor it this way, considering that there’s little to gain by doing so: the resulting code is even longer and arguably harder to read than the original one.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading