2
str="``;`v`;`v`;``";
template=StringTemplate@str;
TemplateApply[template,CharacterRange["A","Z"]]
(*"A;;;D"*)

I want to get the result as:

(*;A;B;;*)

only slot named 'v' is valued as A and B

one method is to make 'v' into 'v1' and 'v2'

str="`hello`;`v1`;`v2`;`world`";
template=StringTemplate@str;
TemplateApply[template,Association["v1"->"A","v2"->"B"]]

maybe I want to get an elegant way if possible like

TemplateApply[template,Association["v"->{"A","B"}]]
HyperGroups
  • 8,619
  • 1
  • 26
  • 63

2 Answers2

4

I'm not sure if this is what you are looking for, but it results in the desired output.

str = "``;`v`;`v`;``";
template = 
  StringTemplate@str /. 
    TemplateSlot[n_Integer] :> TemplateSlot[n, InsertionFunction -> ("" &)] /. 
    TemplateSlot["v"] :> TemplateSlot["v", InsertionFunction -> (#[[counter++]] &)];

counter = 1; TemplateApply[template, Association["v" -> {"A", "B"}]]

";A;B;"

As a new function

templateApply[t_, assoc_] := 
 Module[{key = First@Keys@assoc, newTemplate, count = 1},
  newTemplate = 
   t /. TemplateSlot[n_Integer] :> TemplateSlot[n, InsertionFunction -> ("" &)] /. 
    TemplateSlot[key] :> TemplateSlot[key, InsertionFunction -> (#[[count++]] &)];
  TemplateApply[newTemplate, assoc]]

str = "``;`v`;`v`;``";
template = StringTemplate@str;

templateApply[template, Association["v" -> {"A", "B"}]]

";A;B;"

Karsten7
  • 27,448
  • 5
  • 73
  • 134
2

I will do this programmatically in three steps.

  1. Rewrite your string template in this manner:

    "`a`;`b`;`a`;`c`;`a`;`c`" -> "`a0`;`b0`;`a1`;`c0`;`a2`;`c1`"

  2. Rewrite associations to the form required to match the string template generated in the previous step.

  3. Write a wrapper function that takes the rewritten string template and the rewritten association that now matches the string template and apply the data to the template.

Rewrite string template

Code

rewriteTemplate[tmpl_] := Module[{c},

  c[Alternatives @@ Join[
      CharacterRange["A", "Z"],
      CharacterRange["a", "z"]
      ]] = 0;

  StringReplace[
   tmpl, {
    "``" :> "",
    "`" ~~ l : LetterCharacter ~~ "`" :> StringJoin[
      "`", l, ToString[c[l]++], "`"
      ]
    }]
  ]

Example

template = "`a`;`b`;`a`;`c`;`a`;`c`";

rewriteTemplate[template]

"`a0`;`b0`;`a1`;`c0`;`a2`;`c1`"

Reformat input data (association)

Code

makeInput[Rule[key_, val_]] := Module[{c = 0},

  MapIndexed[
   Rule[key <> ToString[c++], #] &,
   val
   ]
  ]
makeInput[assoc_Association] := AssociationMap[makeInput, assoc]

Example

data = <|
   "a" -> CharacterRange["a", "z"],
   "b" -> CharacterRange["A", "Z"],
   "c" -> ToString /@ Range[10]
   |>;

makeInput[data]

<|"a0" -> "a", "a1" -> "b", "a2" -> "c", "a3" -> "d", "a4" -> "e", "a5" -> "f", "a6" -> "g", "a7" -> "h", "a8" -> "i", "a9" -> "j", "a10" -> "k", "a11" -> "l", "a12" -> "m", "a13" -> "n", "a14"...

Wrap it up!

Code

templateApply[template_, data_] := StringTemplate[
   rewriteTemplate[template]
   ][makeInput@data]

Example

templateApply[template, data]

a;A;b;1;c;2

C. E.
  • 70,533
  • 6
  • 140
  • 264