Условное накопление scala

Я пытаюсь реализовать функцию, которая извлекает из строки список «заполнителей». Символ-разделитель для начального и конечного заполнителей - $. У меня есть несколько идей, как реализовать его с помощью 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
}

Для ясности: в этом примере вы хотите, чтобы все строки находились между совпадающими символами $? Можете ли вы опубликовать код, который у вас есть в настоящее время, чтобы мы имели некоторое представление о том, в каком направлении вы начали?

Ethan 27.09.2018 00:49

Я обновил вопрос примером использования var

user10386912 27.09.2018 01:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
158
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Достаточно ли этого решения?

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 слово accumulate обычно переводится как вариант fold или reduce.

def

 extractValues(s: String) =
  {
    //We can combine the functionality of your boolean and stringbuilder by using an Option
    s.foldLeft[(ListBuffer[String],Option[StringBuilder])]((new ListBuffer[String], Option.empty))
                  {
                    //As we fold through, we have the accumulated list, possibly a partially built String, and the current letter
                    case ((accumulator,sbOption),char) =>
                    {
                      char match
                      {
                        //This logic pretty much matches what you had, adjusted to work with the Option
                        case '$' =>
                        {
                          sbOption match
                          {
                            case Some(sb) =>
                            {
                              accumulator.append(sb.mkString)
                              (accumulator,None)
                            }
                            case None =>
                            {
                              (accumulator,Some(new StringBuilder))
                            }
                          }
                        }
                        case _ =>
                        {
                          sbOption.foreach(_.append(char))
                          (accumulator,sbOption)
                        }
                      }
                    }
                  }._1.map(_.mkString).toList
  }

Однако это кажется довольно сложным, поскольку кажется, что это должна быть простая задача. Мы можем использовать регулярные выражения, но это страшно, поэтому давайте их избегать. На самом деле, если немного подумать, эта проблема становится довольно простой.

 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
  }

Другие вопросы по теме