Scala - замена текстовых заполнителей в строке

Допустим, у меня есть строковый шаблон, который содержит N заполнителей:

"{placeholder1}/{placeholder2}-{placeholder3}/{placeholder4}.{placeholder5}"

Допустим, у меня есть карта:

"placeholder1" -> "aaa", 
"placeholder2" -> "xxx", 
"placeholder3" -> "yyy", 
"placeholder4" -> "zzz", 
"placeholder5" -> "bbb"

Можно ли с учетом этого шаблона строки карты и заполнителя заменить ключи заполнителя значениями заполнителя? Или для этого потребуется использовать регулярное выражение?

В чем разница между методом "==" и equals()
В чем разница между методом "==" и equals()
Это один из наиболее часто задаваемых вопросов новичкам на собеседовании. Давайте обсудим его на примере.
Замена символа по определенному индексу в JavaScript
Замена символа по определенному индексу в JavaScript
В JavaScript существует несколько способов заменить символ в строке по определенному индексу.
0
0
603
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

вы можете перебирать данные и применять их к шаблону, используя String.replace, и продолжать итерацию для нового состояния.

Данный,

scala> val template = "{placeholder1}/{placeholder2}-{placeholder3}/{placeholder4}.{placeholder5}"
template: String = {placeholder1}/{placeholder2}-{placeholder3}/{placeholder4}.{placeholder5}

scala> val data = Map("placeholder1" -> "aaa", 
                      "placeholder2" -> "xxx", 
                      "placeholder3" -> "yyy", 
                      "placeholder4" -> "zzz", 
                      "placeholder5" -> "bbb")
data: scala.collection.immutable.Map[String,String] = HashMap(placeholder5 -> bbb, placeholder1 -> aaa, placeholder3 -> yyy, placeholder2 -> xxx, placeholder4 -> zzz)

применить шаблон к данным с помощью foldLeft. Я предполагаю, что {} указывает на заполнитель шаблона.

scala> data.foldLeft(template){ case (newState, kv) => newState.replace(s"{${kv._1}}", kv._2)}
res6: String = aaa/xxx-yyy/zzz.bbb

ЗАМЕТКА:kv выше - это каждая запись в Map, в качестве альтернативы вы можете деконструировать kv как (k, v).

scala> data.foldLeft(template){ case (newState, (k, v)) => newState.replace(s"{$k}", v)}
res7: String = aaa/xxx-yyy/zzz.bbb

Альтернативное решение:

Хотя .foldLeft достаточно, вы можете написать свою собственную ванильную рекурсию, которая применяет одну запись за раз и продолжает повторять, пока данные не станут пустыми.

def format(template: String, data: Map[String, String]): String = {
  if (data.isEmpty) template
  else format(template.replace(s"{${data.head._1}}", data.head._2), data.tail)
}

val formatted = format(template, data) // aaa/xxx-yyy/zzz.bbb

Хорошо, но если у вас case (newState,(k,v)), то вы можете просто replace(s"{$k}", v).

jwvh 15.12.2018 05:35

почему бы не использовать строковая интерполяция

def replace(m: Map[String,String]) = s"${m("placeholder1")}/${m("placeholder2")}-...."

Поскольку шаблон строки может быть динамическим, возможно ли, чтобы этот метод взял шаблон строки и также использовал интерполяцию?

code 15.12.2018 20:11

не то, о чем я знаю - но если числа заполнителей в порядке (1,2,3, ..), вы можете их подсчитать, а затем, возможно, принять шаблон способом, подходящим для использования String.format ("% s /% s -% s /% s.% s ", m (" placeholder1 ") ...)

Arnon Rotem-Gal-Oz 15.12.2018 20:56

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