user7460099
user7460099

Reputation: 51

Replace object keys with values in given string pattern

I have a task to replace all keys in string pattern with their values. The input is something like that:

[
  '{ "name": "John", "age": 13 }',
  "My name is #{name} and I am #{age}-years-old"
]

And the output is this: 'My name is John and I am 13-years-old'.
So I come up with this:

function FillTemplate() {
if (arguments.length < 2 || arguments.length > 7) {
    console.log('The input objects should be at least 1 and lesser than 7!');
}

for (let i = 0; i <= arguments.length - 2; i += 1) {
    JSON.parse(arguments[i]);

     for (let j = 0; j < Object.keys(arguments[i]).length; i += 1) {
         let currentKey = Object.keys(arguments[i])[j];
         console.log(currentKey);
     }
}
}

I have a problem when i console.log(currentKey) i got only zeros but my idea is take the first object in the input then json.parse it next take all the keys in that object and with one loop take every single key separately and replace it in the pattern string with regex pattern. But this Object.keys return only zeros to me. Where is the problem?

Upvotes: 1

Views: 1902

Answers (2)

Shilly
Shilly

Reputation: 8589

Try the other way around, parse the template string first, then loop over the keys you need so you can reference them directly in the object. Also, I have no idea what you're trying to do with the arguments object.

    // Our source array containing a data string and a template string
var source = [
        '{"name": "John", "age": 13 }',
        'My name is #{name} and I am #{age}-years-old'
    ],
    // helper function to grab all the parameters from a template string
    parseTemplate = function parseTemplate( template ) {
        var regex = /#\{(.+?)\}/g,
            parameters = [],
            nextParameter;
        do {
            // this regexp will grab the next series of characters surrounded by #{}
            nextParameter = regex.exec(template);
            if (nextParameter) parameters.push(nextParameter[1]);
        }
        // as long as there are parameters left, keep searching
        while (nextParameter);
        return parameters;
    },
    // population function, uses parseTemplate to get the parameters and then adds them to the template
    populateTemplate = function populate( template, data ) {
        var parametersToSaturate = parseTemplate(template);
        // for each parameter found, repalce that parameter in the string with the value from the data
        return parametersToSaturate.reduce(function( saturatedTemplate, parameter ) {
            return saturatedTemplate.replace('#{' + parameter + '}', data[parameter] || ('#{' + parameter + '}'));
        }, template);
    },
    result = populateTemplate( source[1], JSON.parse(source[0]) );
console.log(result);

As long as you keep the array returned from parseTemplate is the same order, you can reuse any parameter as many times in a string as you want. Any #{val} parameter not found in the data will just remain.

If you have multiple objects, you can just loop over them.

sources.forEach(function( source ) {
    console.log(populateTemplate( source[1], JSON.parse(source[0]) ));
});

If your browser supports it, you can use actual JS template strings: https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Template_literals

Upvotes: 0

Saerdn
Saerdn

Reputation: 228

Here you go:

<script>
var foo = {
    "name" : "John",
    "age"  : 13
}
var string = "My name is #{name} and I am #{age}-years-old";

// Extract all templates (#{name}, #{age}, ...)
var matches = string.match(/#{[a-zA-Z]+?}/g);
if ( matches ) {
    matches.forEach(function(templateStringToReplace) {
        // Strip the special characters to dynamically get the indices of the object
        templateString = templateStringToReplace.replace(/#|{|}/g, "");
        string = string.replace(templateStringToReplace, foo[templateString])
    });
}

alert(string);

Upvotes: 2

Related Questions