Santiya
Santiya

Reputation: 195

Return value of string

I have the string format, which contains the numbers {0}, {1}, {2}. And I want this numbers to be replaced by the words written from the placeholder in the input type placeholder = "Outside,beautiful,blue", i.e. the value of format[i+1] be equal to index of the string words(contains the words in placeholder). And in the console as a result to get something like this:

Outside is so beautiful with blue sky, beautiful nature and house next to the blue pacific ocean...

HTML:

<!Doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta name="viewport" content="width=device-width">
        <meta charset="utf-8">
        <title>Exercises in JS</title>
        <script src="exercises.js"></script>
    <body>
        <label for="myText">Input array:</label>
            <input type="text" name="wordcount" id="myText" placeholder = "Outside,beautiful,blue" value="" />
        <a href="#" id="sub">Submit</a>
    </body>
    </head>
</html>

Javacript code:

window.onload = function(){

inputBox = document.getElementById("myText");
btn = document.getElementById('sub');   

btn.addEventListener("click",function(event){
event.preventDefault();
    stringFormat(inputBox.value);   
});

    str = inputBox.value;
    var format = '{0} is so {1} with {2} sky, {1} nature and house next to the {2} pacific ocean...';

    function stringFormat(str) {
        var words = document.getElementById("myText").placeholder.split(",");

        for (var i = 0; i < format.length; i++) {
            if (format[i] === '{' && format[i+1] == '0') {
                format = format.replace(format[i+1], words[i]);        
            }

            else if (format[i] === '{' && format[i+1] > '0') {
                format = format.replace(format[i+1], words['$[i]']);
            }
        }
        console.log(format);       
    }
} 

Upvotes: 0

Views: 63

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074415

There are two ways to do this:

  1. Loop through the placeholders in the string, retrieving the equivalent word. This is really easy to do with String#replace's callback function and a regular expression.

  2. Loop through the words and use individual operations to replace "{" + indexOfWord + "}" with the relevant word.

I'd use #1, which looks like this:

function stringFormat(str, words) {
    return str.replace(/\{(\d+)\}/g, function(m, c0) {
        return words[c0] || "";
    });
}

Details:

  • The regular expression /\{(\d+)}/ looks for the pattern {n} where n is a number, and captures the n in a capture group.
  • replace calls its callback function with an argument for the overall match it found (so, for instance, "{0}") followed by the value of any capture groups. Since we have a capture group around the digits, the second argument we get will be just those digits, e.g. "0".
  • We use that to index into the array of words (remember, array indexes aren't really numbers because arrays aren't really arrays, it's fine that we're using a string) to look up the equivalent word.
  • In case there's a placeholder that doesn't have a matching word, we use the curiously-powerful || operator to get "" if words[c0] is undefined.
  • We return the string we want used for each replacement, which replace puts in the result string for us.

(Both links above are to my anemic little blog.)

Example:

function stringFormat(str, words) {
  return str.replace(/\{(\d+)\}/g, function(m, c0) {
    return words[c0] || "";
  });
}

console.log(
  stringFormat(
    "{0} is so {1} with {2} sky, {1} nature and house next to the {2} pacific ocean...",
    "Outside,beautiful,blue".split(",")
  )
);

But if you prefer #2, it's also entirely feasible; you still have to use a regular expression in order to replace all of the placeholders:

function stringFormat(str, words) {
    words.forEach(function(word, index) {
        // (Have to escape `{` because it's a quantifier)
        str = str.replace(new RegExp("\\{" + index + "}", "g"), word);
    });
    return str;
}

In that example, we have to escape { because it has special meaning in regular expressions. (We could also escape }, but we don't have to; it only has special meaning when it's in a pair with an unescaped {.)

Example:

function stringFormat(str, words) {
  words.forEach(function(word, index) {
    // (Have to escape `{` because it's a quantifier)
    str = str.replace(new RegExp("\\{" + index + "}", "g"), word);
  });
  return str;
}

console.log(
  stringFormat(
    "{0} is so {1} with {2} sky, {1} nature and house next to the {2} pacific ocean...",
    "Outside,beautiful,blue".split(",")
  )
);

but you'll want to escape any characters in word that are special in regular expressions, should there be any (I didn't bother above), and it requires multiple passes through the string. So on the whole, #1.

Upvotes: 1

georg
georg

Reputation: 214959

Sounds like a job for regular expressions:

str = "{0} is so {1} with {2} sky, {1} nature and house next to the {2} pacific ocean..."

words = 'Outside,beautiful,blue'.split(',')

result = str.replace(/{(\d+)}/g, m => words[m[1]]);

console.log(result)

Without regexes, it would be a one-liner either:

str = "{0} is so {1} with {2} sky, {1} nature and house next to the {2} pacific ocean..."

words = 'Outside,beautiful,blue'.split(',')

result = words.reduce((str, word, n) => str.split('{' + n + '}').join(word), str);

console.log(result)

Upvotes: 2

Related Questions