Home > Software design >  String manipulation in Kotlin
String manipulation in Kotlin

Time:11-19

I have an application version string. The structure of the versioning is x.x.x.x I am using Kotlin to parse this value and I am trying to only pull the major.minor out of the version string, or x.x. I am struggling to find any String methods that can accomplish this.

Code:

fun main() {
    val appVersion = "15.2.855.15"
    val majorMinorVersion = appVersion.substring(0,4)
    println(majorMinorVersion)
}

Output:

15.2

I have tried using Substring, and that works most of the time if the major version is double digits. But, if it is single digits, then the output is 6.2.. This can also go south if the minor version is double digits etc. I need a method where it will always print major.minor, no matter if major/minor are double or single digits.

CodePudding user response:

We can do it in functional style:

"15.2.855.15"
    .splitToSequence(".")
    .take(2)
    .joinToString(".")

Or we can look for the second . and then take a substring:

var counter = 2
"15.2.855.15".takeWhile { if (it == '.') counter--; counter > 0 }

This is harder to read, but probably has better performance as it avoids creating temporary data structures.

CodePudding user response:

I think a clear way of doing this would be to split the string in its parts, and build the major.minor afterwards:

val appVersion = "15.2.855.15"
val (major, minor) = appVersion.split(".")
val majorMinorVersion = "$major.$minor"

Note: split() actually gives a list of 4 elements (the 4 parts of the version), but the destructuring declaration only takes the 2 first elements because 2 variables are in the parentheses.

Another approach as mentioned in the comments is to use indexOf to find the position of the dot:

val secondDotIndex = appVersion.indexOf(".", appVersion.indexOf(".")   1)
val majorMinorVersion = appVersion.take(secondDotIndex)

You could also use a Regex, but that would be overkill IMO:

val appVersion = "15.2.855.15"
val versionRegex = Regex("""(\d \.\d )\.\d \.\d """)
val versionMatch = versionRegex.matchEntire(appVersion) ?: error("unexpected version format $appVersion")
val majorMinorVersion = versionMatch.groupValues[1]

Or a bit simpler but less reliable:

val appVersion = "15.2.855.15"
val majorMinorRegex = Regex("""\d \.\d """)
val majorMinorVersion = majorMinorRegex.find(appVersion)?.value ?: error("unexpected version format $appVersion")
  • Related