英文:
How to convert a String into list of Integer in Scala
问题
val numbersList = "1,3,5-10".split(",").flatMap {
case rangePattern(start, end) if start.toInt <= end.toInt =>
(start.toInt to end.toInt).toList
case singleNumber => List(singleNumber.toInt)
}.toList
In this code, we use the split
method to split the input string by commas, and then we use flatMap
to transform each element based on whether it is a range (e.g., "5-10") or a single number (e.g., "1" or "3"). We use pattern matching to extract the start and end values from the range and generate a list of integers for each range. For single numbers, we convert them to integers and return them as a list. Finally, we use toList
to collect all the integers into a single list.
This code achieves the desired conversion in a more concise and functional way compared to the original code you provided.
英文:
I have a string 1,3,5-10
and I have to convert this string into a list of integer in scala.
The list will like this --->>. List(1,3,5,6,7,8,9,10)
How will be the best way to convert a string list into an integer list using flatMap
.
or What will the minimal line of code in Scala to do this.
This is the code I have tried to achieve it but I wanted a better way to do so
val selectedNumberList: mutable.MutableList[Int] = mutable.MutableList[Int]()
val numbersList = "1,3,5-10".split(",").toList
for(i <- 0 until numbersList.size ){
if(numbersList(i).contains("-")){
val splitNumberToList = numbersList(i).split("-").toList
for(j <- splitNumberToList.head.toInt to splitNumberToList.last.toInt){
selectedNumberList += j
}
}else{
selectedNumberList += numbersList(i).toInt
}
}
The above code does not use the flat map but can we do this in a better way.
答案1
得分: 2
以下是Scala 2.13的最短代码行,用于处理输入示例并使用flatMap
生成预期输出:
"1,3,5-10".split(',')
.toList
.flatMap{case s"$a-$b" => a.toInt to b.toInt;
case a => a.toInt::Nil}
P.S. 对于错误处理(如果需要),您可以捕获异常或使用Try
,它在底层执行此操作。
P.P.S. 代码被格式化为一行,以便更容易计算其长度。
英文:
Here is a shortest line of code for Scala 2.13 that for the input sample produces an expected output using flatMap
:
scala> "1,3,5-10".split(',')
.toList
.flatMap{case s"$a-$b" => a.toInt to b.toInt;
case a => a.toInt::Nil}
res0: List[Int] = List(1, 3, 5, 6, 7, 8, 9, 10)
P.S. For error handling (if it is required) you can catch exceptions or use Try
which do this underhood.
P.P.S. Code was formatted as a one-liner for easier counting of its length
答案2
得分: 1
以下是翻译好的代码部分:
import scala.util.Try
// 验证正则表达式
def validateRegex(input: String): Try[Unit] = Try(if(!input.matches("((\\d+-\\d+|\\d+)(\$|(,\\s+)?))+")) throw new Exception(""))
// 验证范围
def validateRange(input: String): Try[Unit] = Try {
val pattern = "\\d+-\\d+".r
(pattern findAllIn input).toList.map(_.split("-").map(_.toInt)).map(_.toList).map {
case a :: b :: Nil if a >= b => throw new Exception("")
case _ =>
}
}
// 验证输入
def validateInput(input: String): Boolean = {
val list: List[Try[Unit]] = List(
validateRegex(input),
validateRange(input)
)
!list.exists(_.isFailure)
}
// 转换输入为列表
def inToOut(input: String): List[Int] = {
if(validateInput(input)) input.split(",\\s?").flatMap {
case r if r.contains("-") =>
val s = r.split("-").map(_.toInt)
(s(0) to s(1)).toList
case i => List(i.toInt)
}.toList else List()
}
请注意,这是代码的中文翻译部分,不包括其他内容。
英文:
Here's somewhere to start:
import scala.util.Try
def validateRegex(input: String): Try[Unit] = Try(if(!input.matches("((\\d+-\\d+|\\d+)($|,(\\s+)?))+")) throw new Exception(""))
def validateRange(input: String): Try[Unit] = Try {
val pattern = "\\d+-\\d+".r
(pattern findAllIn input).toList.map(_.split("-").map(_.toInt)).map(_.toList).map {
case a :: b :: Nil if a >= b => throw new Exception("")
case _ =>
}
}
def validateInput(input: String): Boolean = {
val list: List[Try[Unit]] = List(
validateRegex(input),
validateRange(input)
)
!list.exists(_.isFailure)
}
def inToOut(input: String): List[Int] = {
if(validateInput(input)) input.split(",\\s?").flatMap {
case r if r.contains("-") =>
val s = r.split("-").map(_.toInt)
(s(0) to s(1)).toList
case i => List(i.toInt)
}.toList else List()
}
You call inToOut
with your String and it either spits out an empty List (if your String is invalid) or a populated List if everything is formatted correctly.
However
This is incomplete.
- This isn't very condense - you can shorten it considerably, but this code is laid out in a way that is (hopefully) understandable.
- You'll need to add in more (or different) error handling - your question doesn't specify any sort of error handling, so I've implemented a couple of validations that you could do to get you going but you'll need to decide what the limits of your function are (String format, range rules, ordering, duplicate values, etc).
- There's probably a quicker way of implementing this without throwing an exception every time something goes wrong. Depends on your implementation; I'll leave this up to you.
- I haven't accounted for negative numbers (again something for you to implement if you need to).
Anyway, here's an implementation of it working with some success and failure examples: https://scastie.scala-lang.org/FmUsQZQGQIC6X6JRmFLVjg
答案3
得分: 0
我已经尝试过这段代码,现在它对我来说运行得很好。
val numbers = "1,3,5-10".split(",").toList.flatMap{
case x if x.contains("-") =>
val k = x.split("-")
k.head.toInt to k(1).toInt
case a => a.toInt::Nil
}
英文:
I have tried this code and it is working fine for me now.
val numbers = "1,3,5-10".split(",").toList.flatMap{
case x if x.contains("-") =>
val k = x.split("-")
k.head.toInt to k(1).toInt
case a => a.toInt::Nil
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论