简体   繁体   English

Kotlin 将字符串拆分为范围

[英]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).因此,例如,我有字符串“10;15;1”,我需要得到从 10 到 15 的范围(忽略最后一个数字)。

Expecting result:预期结果:

"10;15;1" -> 10..15 “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: 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: 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. function 非常具体,因此它不能存在于标准库中。 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.尽管我可以建议使用正则表达式的替代方法并在字符串格式不正确的情况下返回 null 值,但我并不反对该实现。 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.或者您可以更新您的 function 检查split生成的列表的长度是否>= 2并直接使用arr[0].toBigDecimal().. arr[1].toBigDecimal但它并没有太大的不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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