code
code

Reputation: 5642

Scala - Replace text placeholders in a String

Lets say that I have a string template which contains N number of placeholders:

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

And let's say that I have a map:

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

Given this map and placeholder string template, is it possible to replace the placeholder keys with the placeholder values? Or would this require using regex?

Upvotes: 0

Views: 1002

Answers (2)

prayagupadhyay
prayagupadhyay

Reputation: 31212

you can iterate over the data and apply to the template using String.replace, and keep iterating on new state.

Given,

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)

apply the template on data using foldLeft. I'm assuming {} indicates the template placeholder.

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

NOTE: kv above is each entry in Map, alternatively, you can deconstruct kv as (k, v).

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

Alternative solution:

Though .foldLeft is enough, you can write your own vanilla recursive that applies one entry at a time and keeps iterating until data is empty.

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

Upvotes: 4

Arnon Rotem-Gal-Oz
Arnon Rotem-Gal-Oz

Reputation: 25909

why not use string interpolation

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

Upvotes: 0

Related Questions