Python format string but in JS

TL;DR

/**
 *
 * @param {string} str
 * @param  {...any} values
 * @returns
 */
function format(str, ...values) {
  if (typeof str !== "string" || str instanceof String) {
    return false;
  }

  let re = /\{(\w+)\}/g; // match curl bracket and value inside
  let replaceWith = [...values]; // get a copy 
  let allCurly = str.match(re) || []; // get all curl bracket
  for (let i = 0; i < allCurly.length; i++) { // loop through the curl bracket
    str = str.replace(allCurly[i], replaceWith[i]); // replace them in str
  }
  return str;
}

console.log(format("{a} {b} {d}", "daniel", "codex", "it's somthing"));
console.log(format("{a} something really cool", "daniel"));
console.log(format("{something}", "daniel"));
console.log(format("{1} {wow} {3}", "daniel", "codex", "something"));
console.log(format("{1} {2} {3}", 1, 2, 3));
console.log(format("{1}", "hello")); 

Explanation

So format string in python is written as follows:

name = "daniel"
lname = "sparrow"
res = "{} {}".format(name, lname)
print(res) # daniel sparrow

We are going to make something like this.
Here is how it’s going to look like.

format("{a} {b}", "daniel", "codex")
// daniel codex

so it’s a bit different than python version 😅

First of all for us will be a function but for python it’s string method.
And for python have a lot more feature which u can check them out here 👇

https://www.programiz.com/python-programming/methods/string/format

Our function parameter will look like this:

format(str, ...values)


In str we are going to have string with placeholder in {a} or {1} format.

And we have ...values. in this blog i am not going to talk about rest parameter, if you like to learn more read this article. basically we use rest parameter in the case that user want to use more than one arguments.

So What’s the idea? there would always be some unique values (let’s call them placeholder) in the string in the form of {a} or {1} our job is to replace it with values.

Here is how the regex will look like 👇

let re = /\{(\w+)\}/g;
let allCurly = str.match(re) || [];

With this code we are going to find all of the placeholder, and if we can not find them we will return [] (that’s what the || [] do)

Also we get the copy of our value (because i don’t like mutate stuff):

let replaceWith = [...rest]

Then we have to loop through all of the allCurly and replace it with replaceWith with the helps of replace method.

for (let i = 0; i < allCurly.length; i++){
    str = str.replace(
      allCurly[i],
      replaceWith[i]
    )
  }

That’s how you get something similar to python format string in JS.

Challenge

How about a challenge?

  1. Right now what we just implement is a function, how about making it a string method?

Hint: you have to use something like this 👇

String.prototype.format = function() {
 // 
}

2. The problem with regex is that, we can write expression between placeholder like {str.toUpperCase()}, can you find a way to run an expression?

I don’t know how to do that myself, if you did figure it out let me know @Daniel_Codex

Inspiration

I found a really interesting tweet by @betterways_dev. His solution also is really interesting.

Make sure to check his blog.

Leave a Reply

Your email address will not be published. Required fields are marked *