【问题标题】:Split string with default value in scala在scala中使用默认值拆分字符串
【发布时间】:2023-03-18 09:45:01
【问题描述】:

我有一个如下所示的字符串列表,其中列出了水果以及与每个相关的成本。如果没有值,则假定为5:

val stringList: List[String] = List("apples 20", "oranges", "pears 10")

现在我想拆分字符串以获得水果和成本的元组。这样做的scala方式是什么?

stringList.map(query => query.split(" ")) 

不是我想要的。

found this 这是相似的。这样做的正确Scala方式是什么?

【问题讨论】:

  • 映射一个自定义函数,如果缺少第二个元素,该函数会拆分然后添加一个元素。

标签: scala tuples default-value


【解决方案1】:

您可以使用正则表达式和模式匹配:

val Pat = """(.+)\s(\d+)""".r  // word followed by whitespace followed by number

def extract(in: String): (String, Int) = in match {
  case Pat(name, price) => (name, price.toInt)
  case _                => (in, 5)
}

val stringList: List[String] = List("apples 20", "oranges", "pears 10")

stringList.map(extract) // List((apples,20), (oranges,5), (pears,10))

模式中有两个捕获组。这些将被提取为字符串,因此您必须使用.toInt 进行显式转换。

【讨论】:

  • 这里有更多关于模式匹配的内容:stackoverflow.com/questions/4636610/…
  • val r = """(\S+)\s*(\d+)?""".r ; def f(s: String) = s match { case r(n, null) => (n, 42) case r(n, i) => (n, i.toInt) case _ => (0,0) } 显示处理空的第二组。正则表达式对验证有很大帮助。
  • @som-snytt 谢谢,我的正则表达式 foo 相当有限
【解决方案2】:

你几乎拥有它:

stringList.map(query => query.split(" ")) 

你想要的,只需添加另一个地图即可将列表更改为元组:

.map { list => list.head -> list.lift(1).getOrElse("5").toInt }

或者这个,如果你愿意的话:

.collect { 
    case Seq(a, b) => a -> b.toInt
    case Seq(a) => a -> 5
 }

.collect 将默默地忽略列表中少于一个或多于两个元素的出现。如果您希望在这种情况下出现错误,可以将其替换为 .map)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    • 2019-05-07
    相关资源
    最近更新 更多