Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
scala条件累加_Scala - Fatal编程技术网

scala条件累加

scala条件累加,scala,Scala,我正在尝试实现一个函数,该函数从字符串中提取“占位符”列表。开始占位符和结束占位符的分隔符字符为$。我有一些想法如何实现它使用一个var来启用/禁用累加,我试图做的是在没有任何var的情况下实现它 对于像这样的字符串 val stringToParse = "ignore/me/$aaa$/once-again/ignore/me/$bbb$/still-to-be/ignored 结果应该是 Seq("aaa", "bbb") 有什么提示吗 下面是一个使用var的解决方案 import f

我正在尝试实现一个函数,该函数从字符串中提取“占位符”列表。开始占位符和结束占位符的分隔符字符为$。我有一些想法如何实现它使用一个var来启用/禁用累加,我试图做的是在没有任何var的情况下实现它

对于像这样的字符串

val stringToParse = "ignore/me/$aaa$/once-again/ignore/me/$bbb$/still-to-be/ignored
结果应该是

Seq("aaa", "bbb")
有什么提示吗

下面是一个使用var的解决方案

import fiddle.Fiddle, Fiddle.println
import scalajs.js
import scala.collection.mutable.ListBuffer

@js.annotation.JSExportTopLevel("ScalaFiddle")
object ScalaFiddle {
  // $FiddleStart


  val stringToParse = "ignore/me/$aaa$/once-again/ignore/me/$bbb$/still-to-be/ignored"

  class StringAccumulator {

    val accumulator: ListBuffer[String] = new ListBuffer[String]
    val sb: StringBuilder = new StringBuilder("")
    var open:Boolean = false

    def next():Unit = {
      if (open) {
        accumulator.append(sb.toString)
        sb.clear
        open = false
      } else {
        open = true
      }
    }

    def accumulateIfOpen(charToAccumulate: Char):Unit = {
      if (open) sb.append(charToAccumulate)
    }

    def get(): Seq[String] = accumulator.toList
  }

  def getPlaceHolders(str: String): Seq[String] = {
    val sac = new StringAccumulator

    str.foreach(chr => {
      if (chr == '$') {
        sac.next()
      } else {
        sac.accumulateIfOpen(chr)
      }
    })

    sac.get
  }

  println(getPlaceHolders(stringToParse))
  // $FiddleEnd
}

这个解决方案够了吗

scala> val stringToParse = "ignore/me/$aaa$/once-again/ignore/me/$bbb$/still-to-be/ignored"
stringToParse: String = ignore/me/$aaa$/once-again/ignore/me/$bbb$/still-to-be/ignored

scala> val P = """\$([^\$]+)\$""".r
P: scala.util.matching.Regex = \$([^\$]+)\$

scala> P.findAllIn(stringToParse).map{case P(s) => s}.toSeq
res1: Seq[String] = List(aaa, bbb)

我将向您介绍两种解决方案。第一个是你所做的最直接的翻译。在Scala中,如果您听到单词
acculate
,它通常会转换为
fold
reduce
的变体

def

然而,这似乎相当复杂,因为听起来应该是一项简单的任务。我们可以使用正则表达式,但它们很可怕,所以让我们避免使用它们。事实上,经过一点思考,这个问题实际上变得相当简单

 def extractValuesSimple(s: String)=
  {
    s.split('$').//split the string on the $ character
      dropRight(1).//Drops the rightmost item, to handle the case with an odd number of $
      zipWithIndex.filter{case (str, index) => index % 2 == 1}.//Filter out all of the even indexed items, which will always be outside of the matching $
      map{case (str, index) => str}.toList//Remove the indexes from the output
  }

需要明确的是,在本例中,您希望所有字符串都位于匹配的$?你能发布你目前拥有的代码吗,这样我们就知道你开始的方向了?我已经用var更新了这个问题
 def extractValuesSimple(s: String)=
  {
    s.split('$').//split the string on the $ character
      dropRight(1).//Drops the rightmost item, to handle the case with an odd number of $
      zipWithIndex.filter{case (str, index) => index % 2 == 1}.//Filter out all of the even indexed items, which will always be outside of the matching $
      map{case (str, index) => str}.toList//Remove the indexes from the output
  }