Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient template population

Say I have a text template with a number of fields that need to be populated:

var template = "hello {$name}. you are {$age} years old. you live in {$location}"

and an IDictionary<string,string> of values to substitute:

key     | value
===================
name    | spender
age     | 38
location| UK

The naive way of populating the template might be something like:

var output = template;
foreach(var kvp in templValues)
{
    output = output.Replace(string.format("{{${0}}}", kvp.Key), kvp.Value);
}

However, this seems painfully inefficient. Is there a better way?

like image 586
spender Avatar asked Jan 26 '12 11:01

spender


People also ask

What is infographics example?

What is an infographic example? An infographic example is a visual representation of information. Infographics examples include a variety of elements, such as images, icons, text, charts, and diagrams to convey messages at a glance.


2 Answers

There's nothing wrong with your approach, it depends on the context it's being used. For example, in a tight mission-critical loop it's not the most efficient approach, but for occasional use, or in a gui it's probably ok.

A more efficient solution would be to parse the string. For example. search for the first { and then for the next }. The text between them is the key to lookup, which you can then substitute. You then start with the searching from the character after the }. The advantage of this approach is that if the value you insert has an embedded token it won't be replaced. The disadvantage is that it's more difficult to handle the edge cases when parsing.

like image 182
Sean Avatar answered Sep 28 '22 05:09

Sean


You could use a Regex.Replace(), like this:

var output = new Regex(@"\{\$([^}]+)\}").Replace(
    template,
    m => templValues.ContainsKey(m.Captures[1].Value)
        ? templValues[m.Captures[1].Value]
        : m.Value);

AFAIK this will also prevent unexpected results if your dictionary is built like this, because this might produce "hello UK. you are 38 years old. you live in UK" as well as "hello {$location}. you are 38 years old. you live in UK", since dictionarys don't sort their keys:

key     | value
===================
name    | {$location}
age     | 38
location| UK

When the first behavior is actually desired, you can just run the regex multiple times.

Edit: If the template parsing is actually in a time critical part of the code, don't do the template parsing there. you should consider using the manual parsing method Sean recommended.

like image 23
Nuffin Avatar answered Sep 28 '22 04:09

Nuffin