简体   繁体   中英

Kotlin split string into range

I need to get a range from string. ; - is a delimeter.

So, for example i have string "10;15;1" and i need to get range from 10 to 15(ignoring the last number).

Expecting result:

"10;15;1" -> 10..15

So i tryed to write this code. How can i improove it? it looks bad and innefective

val arr = "10;15;1".split(";").dropLast(1).map { it.toBigDecimal() }
val someRange = arr[0] .. arr[1]

If you don't care about validation, you could do this:

fun toRange(str: String): IntRange = str
    .split(";")
    .let { (a, b) -> a.toInt()..b.toInt() }

fun main() {
    println(toRange("10;15;1"))
}

Output:

10..15

If you want to be more paranoid:

fun toRange(str: String): IntRange {
    val split = str.split(";")
    require(split.size >= 2) { "str must contain two integers separated by ;" }

    val (a, b) = split

    return try {
        a.toInt()..b.toInt()
    } catch (e: NumberFormatException) {
        throw IllegalArgumentException("str values '$a' and/or '$b' are not integers", e)
    }
}

fun main() {
    try { println(toRange("oops")) } catch (e: IllegalArgumentException) { println(e.message) }
    try { println(toRange("foo;bar;baz")) } catch (e: IllegalArgumentException) { println(e.message) }
    println(toRange("10;15;1"))
}

Output:

str must contain two integers separated by ;
str values 'foo' and/or 'bar' are not integers
10..15

The function is very specific so it must not exist in the standard library. I have nothing against the implementation although I can suggest alternatives using a Regex and returning a null value if the string is not well formed. But it uses regex.

fun rangeFrom(str: String) : ClosedRange<BigDecimal>? {
    val regex = """^(\d+);(\d+);\d+$""".toRegex()
    val result = regex.find(str)
    return result?.destructured?.let { (fst, snd) ->
        fst.toBigDecimal() .. snd.toBigDecimal()
    }
}

Or you can just update your function checking that the length of the list produced by split is >= 2 and directly using arr[0].toBigDecimal().. arr[1].toBigDecimal but it is not very different.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM