在地图中构建堆栈

时间:2010-12-06 15:56:29

标签: string scala stack split scala-2.8

我有一个看起来像这样的字符串:

 "7-6-4-1"

 "7"

 ""

即,由 - 分隔的一组数字。可能有零个或多个数字。

我想返回一个堆栈,其中按顺序按下数字(即第一个按7,第一个示例为1个)

如果我只是想返回一个列表,我可以去str.split("-").map{_.toInt}(虽然这对空字符串不起作用)/

虽然没有toStack转换为Stack。所以目前,我有

  {
    val s = new Stack[Int]; 
    if (x.nonEmpty)
        x.split('-').foreach {
    y => s.push(y.toInt)
      }
   s
   }

哪个有效,但非常难看。我错过了什么?

编辑:感谢所有响应者,我从这次讨论中学到了很多东西

3 个答案:

答案 0 :(得分:5)

Stack(x.split("-").map(_.toInt).reverse: _*)

这里的技巧是将你从split中获得的数组传递给Stack伴随对象构建器。默认情况下,项目的顺序与数组的顺序相同,因此您必须先反转数组。

请注意“将此视为列表,而不是单项”注释: _*


编辑:如果你不想单独捕获空字符串的情况,就像这样(使用底部的一个用于可变堆栈,顶部用于不可变的):

if (x.isEmpty) Stack() else Stack(x.split("-").map(_.toInt).reverse: _*)
if (x.isEmpty) Stack[Int]() else Stack(x.split("-").map(_.toInt).reverse: _*)

然后你可以过滤掉空字符串:

Stack(x.split("-").filterNot(_.isEmpty).map(_.toInt).reverse: _*)

也会“帮助”为您处理7-9----2-2-4之类的事情(它会给Stack(4,2,2,9,7))。

如果您想处理更糟糕的格式错误,可以

val guard = scala.util.control.Exception.catching[Int](classOf[NumberFormatException])
Stack(x.split("-").flatMap(x => guard.opt(x.toInt)).reverse: _*)

仅返回实际可以解析的项目。

答案 1 :(得分:3)

(Stack[Int]() /: (if(x.isEmpty) Array.empty else x.split("-")))(
                  (stack, value) => 
                      stack.push(value toInt))

答案 2 :(得分:3)

不要忘记一个方便breakOut,它提供的性能略优于col: _*(见Daniel's excellent explanation

此处使用Rex Kerr的.filterNot(_.isEmpty)解决方案:

import scala.collection.immutable.Stack
import scala.collection.breakOut

object StackFromString {

  def stackFromString(str: String): Stack[Int] =
    str.split("-").filterNot(_.isEmpty)
      .reverse.map(_.toInt)(breakOut)

  def main(args: Array[String]): Unit = {
    println(stackFromString("7-6-4-1"))
    println(stackFromString("7"))
    println(stackFromString(""))
  }
}

将输出:

Stack(1, 4, 6, 7)
Stack(7)
Stack()