top of page

Comparing Strings having number on Kotlin and Swift

Both languages have methods for comparing strings. We can compare strings easily using these methods. In kotlin, it is compareTo() and in Swift it is compare().

But we get difficulty when comparing strings that hold numbers and comparison needs to be considering numbers as well. Example: "AB-100", "AB-70". Without considering number: "AB-100", "AB-70" and with considering number: "AB-70","AB-100" In Swift, We can easily solve this problem by using the options parameter of compare(). str1.compare(str2, options: .numeric) But in Kotlin, there are no in-built methods for providing the feature. It is still not found till the 1.5.0 version. I hope the feature will be added soon in Kotlin. But we can easily implement it by ourselves. Please follow the below code.


fun String.compareTo(other: String, isConsiderNumber: Boolean, isNumberDescendingOrder: Boolean = false): Int {
    if (!isConsiderNumber) {
        return this.compareTo(other)
    }
    if (this == other) {
        return 0
    }
    
    var indexOne = 0
    var indexTwo = 0

    var lenOne = 0
    var lenTwo = 0

    while (indexOne < this.length || indexTwo < other.length) {

        if (lenOne != lenTwo) {
            break
        }

        if (indexOne < this.length && indexTwo >= other.length) {
            lenOne += this.length - indexOne
            break
        }

        if (indexTwo < other.length && indexOne >= this.length) {
            lenTwo += other.length - indexTwo
            break
        }

        if (this[indexOne].isDigit() && other[indexTwo].isDigit()) {
            var numStr1 = ""
            while (indexOne < this.length && this[indexOne].isDigit()) {
                numStr1 += this[indexOne++]
            }
            var numStr2 = ""
            while (indexTwo < other.length && other[indexTwo].isDigit()) {
                numStr2 += other[indexTwo++]
            }
            lenOne += (if (isNumberDescendingOrder) numStr2 else numStr1).toInt()
            lenTwo += (if (isNumberDescendingOrder) numStr1 else numStr2).toInt()
        } else if (this[indexOne] != other[indexTwo]) {
            lenOne += this[indexOne].code
            lenTwo += other[indexTwo].code
            break
        } else {
            indexOne++
            indexTwo++
        }
    }

    return lenOne - lenTwo
}

Practical example: versions["2021.10.0", "2021.2.1", "2021.2.0", "2019.10.0", "2020.2.0"] can be sort by this compareTo() method easily in Kotlin.


versions.sortedWith { s1, s2 ->
    s1.compareTo(s2, isConsiderNumber = true)
}

You can find the complete code here.


Comments


bottom of page