如何在Scala中将字符串转换为整数列表

huangapple go评论74阅读模式
英文:

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 = &quot;1,3,5-10&quot;.split(&quot;,&quot;).toList
for(i &lt;- 0 until numbersList.size ){
if(numbersList(i).contains(&quot;-&quot;)){
val splitNumberToList = numbersList(i).split(&quot;-&quot;).toList
    for(j &lt;- 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&gt; &quot;1,3,5-10&quot;.split(&#39;,&#39;)
                 .toList
                 .flatMap{case s&quot;$a-$b&quot; =&gt; a.toInt to b.toInt;
                          case a        =&gt; 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(&quot;((\\d+-\\d+|\\d+)($|,(\\s+)?))+&quot;)) throw new Exception(&quot;&quot;))
def validateRange(input: String): Try[Unit] = Try {
val pattern = &quot;\\d+-\\d+&quot;.r
(pattern findAllIn input).toList.map(_.split(&quot;-&quot;).map(_.toInt)).map(_.toList).map {
case a :: b :: Nil if a &gt;= b =&gt; throw new Exception(&quot;&quot;)
case _ =&gt;
}
}
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(&quot;,\\s?&quot;).flatMap {
case r if r.contains(&quot;-&quot;) =&gt;
val s = r.split(&quot;-&quot;).map(_.toInt)
(s(0) to s(1)).toList
case i =&gt; 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 = &quot;1,3,5-10&quot;.split(&quot;,&quot;).toList.flatMap{
case x if x.contains(&quot;-&quot;) =&gt;
val k = x.split(&quot;-&quot;)
k.head.toInt to k(1).toInt
case a =&gt; a.toInt::Nil
}

huangapple
  • 本文由 发表于 2020年1月7日 00:55:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/59616043.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定