Reputation: 123
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]
Upvotes: 1
Views: 1373
Reputation: 23091
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
Upvotes: 2
Reputation: 637
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.
Upvotes: 0