JavaScript equivalent of Python's format() function?

JavascriptPythonFormat

Javascript Problem Overview


Python has this beautiful function to turn this:

bar1 = 'foobar'
bar2 = 'jumped'
bar3 = 'dog'

foo = 'The lazy ' + bar3 + ' ' + bar2 ' over the ' + bar1
# The lazy dog jumped over the foobar

Into this:

bar1 = 'foobar'
bar2 = 'jumped'
bar3 = 'dog'

foo = 'The lazy {} {} over the {}'.format(bar3, bar2, bar1)
# The lazy dog jumped over the foobar

Does JavaScript have such a function? If not, how would I create one which follows the same syntax as Python's implementation?

Javascript Solutions


Solution 1 - Javascript

Another approach, using the String.prototype.replace method, with a "replacer" function as second argument:

String.prototype.format = function () {
  var i = 0, args = arguments;
  return this.replace(/{}/g, function () {
    return typeof args[i] != 'undefined' ? args[i++] : '';
  });
};

var bar1 = 'foobar',
    bar2 = 'jumped',
    bar3 = 'dog';

'The lazy {} {} over the {}'.format(bar3, bar2, bar1);
// "The lazy dog jumped over the foobar"

Solution 2 - Javascript

There is a way, but not exactly using format.

var name = "John"; var age = 19; var message = My name is ${name} and I am ${age} years old; console.log(message);

jsfiddle - link

Solution 3 - Javascript

tl;dr

foo = (a, b, c) => `The lazy ${a} ${b} over the ${c}`

Why template strings alone aren't enough

ES6 template strings provide a feature quite similar to pythons string format. However, you have to know the variables before you construct the string:

var templateString = `The lazy ${bar3} ${bar2} over the ${bar1}`;

Why format?

Python's str.format allows you to specify the string before you even know which values you want to plug into it, like:

foo = 'The lazy {} {} over the {}'

bar1 = 'foobar'
bar2 = 'jumped'
bar3 = 'dog'

foo.format(bar3, bar2, bar1)

Solution

With an arrow function, we can elegantly wrap the template string for later use:

foo = (a, b, c) => `The lazy ${a} ${b} over the ${c}`

bar1 = 'foobar';
bar2 = 'jumped';
bar3 = 'dog';

foo(bar3, bar2, bar1)

Of course this works with a regular function as well, but the arrow function allows us to make this a one-liner. Both features are available in most browsers und runtimes:

Solution 4 - Javascript

Looking for an answer for the same question, I just found this: https://github.com/davidchambers/string-format, which is "JavaScript string formatting inspired by Python’s str.format()". It seem it's pretty much the same as python's format() function.

Solution 5 - Javascript

Taken from YAHOOs library:

YAHOO.Tools.printf = function() { 
  var num = arguments.length; 
  var oStr = arguments[0];   
  for (var i = 1; i < num; i++) { 
    var pattern = "\\{" + (i-1) + "\\}"; 
    var re = new RegExp(pattern, "g"); 
    oStr = oStr.replace(re, arguments[i]); 
  } 
  return oStr; 
} 

Call it like:

bar1 = 'foobar'
bar2 = 'jumped'
bar3 = 'dog'

foo = YAHOO.Tools.printf('The lazy {0} {1} over the {2}', bar3, bar2, bar1); 

Solution 6 - Javascript

Here's my first attempt. Feel free to point out flaws.

Example: http://jsfiddle.net/wFb2p/5/

String.prototype.format = function() {
    var str = this;
    var i = 0;
    var len = arguments.length;
    var matches = str.match(/{}/g);
    if( !matches || matches.length !== len ) {
        throw "wrong number of arguments";
    }
    while( i < len ) {
        str = str.replace(/{}/, arguments[i] );
        i++;
    }
    return str;
};

EDIT: Made it a bit more efficient by eliminating the .match() call in the while statement.

EDIT: Changed it so that the same error is thrown if you don't pass any arguments.

Solution 7 - Javascript

You can use template literals in JS,

const bar1 = 'foobar'
const bar2 = 'jumped'
const bar3 = 'dog'
foo = `The lazy ${bar3} ${bar2} over the ${bar1}`

I think this was helpful.

Solution 8 - Javascript

Usando split:

String.prototype.format = function (args) {
    var text = this
    for(var attr in args){
        text = text.split('${' + attr + '}').join(args[attr]);
    }
    return text
};

json = {'who':'Gendry', 'what':'will sit', 'where':'in the Iron Throne'}
text = 'GOT: ${who} ${what} ${where}';

console.log('context: ',json);
console.log('template: ',text);
console.log('formated: ',text.format(json));

Usando Regex:

String.prototype.format = function (args) {
    var text = this
    for(var attr in args){
        var rgx = new RegExp('\\${' + attr + '}','g');
        text = text.replace(rgx, args[attr]);
    }
    return text
};

json = {'who':'Gendry', 'what':'will sit', 'where':'in the Iron Throne'}
text = 'GOT: ${who} ${what} ${where}';

console.log('context: ',json);
console.log('template: ',text);
console.log('formated: ',text.format(json));

Solution 9 - Javascript

This code allows you to specify exactly which brackets to replace with which strings. The brackets don't need to be in the same order as the arguments, and multiple brackets are possible. The format function takes an array of values as its parameter, with each key being one of the bracketed 'variables' which is replaced by its corresponding value.

String.prototype.format = function (arguments) {
	var this_string = '';
	for (var char_pos = 0; char_pos < this.length; char_pos++) {
		this_string = this_string + this[char_pos];
	}
	
	for (var key in arguments) {
		var string_key = '{' + key + '}'
		this_string = this_string.replace(new RegExp(string_key, 'g'), arguments[key]);
	}
	return this_string;
};

'The time is {time} and today is {day}, {day}, {day}. Oh, and did I mention that the time is {time}.'.format({day:'Monday',time:'2:13'});
//'The time is 2:13 and today is Monday, Monday, Monday. Oh, and did I mention that the time is 2:13.'

Solution 10 - Javascript

JS:

String.prototype.format = function () {
	var str = this;
	for (var i = 0; i < arguments.length; i++) {
		str = str.replace('{' + i + '}', arguments[i]);
	}
	return str;
}

bar1 = 'foobar';
bar2 = 'jumped';
bar3 = 'dog';

python_format = 'The lazy {2} {1} over the {0}'.format(bar1,bar2,bar3);

document.getElementById("demo").innerHTML = "JavaScript equivalent of Python's format() function:<br><span id='python_str'>" + python_format + "</span>";

HTML:

<p id="demo"></p>

CSS:

span#python_str {
    color: red;
    font-style: italic;
}

OUTPUT:

> JavaScript equivalent of Python's format() function: > > The lazy dog jumped over the foobar

DEMO:

jsFiddle

Solution 11 - Javascript

String.prototype.format = function () {
	var i=0,args=arguments,formats={
		"f":(v,s,c,f)=>{s=s||' ',c=parseInt(c||'0'),f=parseInt(f||'-1');v=f>0?Math.floor(v).toString()+"."+Math.ceil(v*Math.pow(10,f)).toString().slice(-f):(f==-1?v.toString():Math.floor(v).toString());return c>v.length?s.repeat(c-v.length)+v:v;},
		"d":(v,s,c,f)=>{s=s||' ',c=parseInt(c||'0');v=Math.floor(v).toString();return c>v.length?s.repeat(c-v.length)+v:v;},
		"s":(v,s,c,f)=>{s=s||' ',c=parseInt(c||'0');return c>v.length?s.repeat(c-v.length)+v:v;},
		"x":(v,s,c,f)=>{s=s||' ',c=parseInt(c||'0');v=Math.floor(v).toString(16);return c>v.length?s.repeat(c-v.length)+v:v;},
		"X":(v,s,c,f)=>{s=s||' ',c=parseInt(c||'0');v=Math.floor(v).toString(16).toUpperCase();return c>v.length?s.repeat(c-v.length)+v:v;},
	};
	return this.replace(/{(\d+)?:?([0=-_*])?(\d+)?\.?(\d+)?([dfsxX])}/g, function () {
		let pos = arguments[1]||i;i++;
		return typeof args[pos] != 'undefined' ? formats[arguments[5]](args[pos],arguments[2],arguments[3],arguments[4]) : '';
	});
};

Solution 12 - Javascript

Simple implementation without using extra function

[bar1, bar2, bar3].reduce(
  (str, val) => str.replace(/{}/, val),
  'The lazy {} {} over the {}'
)

Solution 13 - Javascript

JavaScript doesn't have such a function AFAIK.

You could create one by modifying the String class's prototype object to add a format() method which takes a variable number of arguments.

In the format method you'd have to get the String's instance value (the actual string) and then parse it for '{}' and insert the appropriate argument.

Then return the new string to the caller.

Solution 14 - Javascript

JavaScript does not have a string formatting function by default, although you can create your own or use one someone else has made (such as sprintf)

Solution 15 - Javascript

In the file

https://github.com/BruceSherwood/glowscript/blob/master/lib/glow/api_misc.js

is a function String.prototype.format = function(args) that fully implements the Python string.format() function, not limited simply to handling character strings.

Solution 16 - Javascript

For those looking for a simple ES6 solution.

First of all I'm providing a function instead of extending native String prototype because it is generally discouraged.

// format function using replace() and recursion

const format = (str, arr) => arr.length > 1 
	? format(str.replace('{}', arr[0]), arr.slice(1)) 
	: (arr[0] && str.replace('{}', arr[0])) || str

// Example usage

const str1 = 'The {} brown {} jumps over the {} dog'

const formattedString = formatFn(str1, ['quick','fox','lazy'])

console.log(formattedString)

Solution 17 - Javascript

If you (like me) only need the limited subset of python's format function for simple string replacement, and performance is not critical, a very simple 29-line pure-Javascript function may suffice.

Javascript call: format(str, data)

Analogous python call: str.format(**data), with the caveat that this javascript function, unlike Python's, does not throw an error if the string contains a varname that is not found in the provided data.

/*
 * format(str, data): analogous to Python's str.format(**data)
 *
 * Example:
 *   let data = {
 *     user: {
 *       name: { first: 'Jane', last: 'Doe' }
 *     },
 *     email: '[email protected]',
 *     groups: ["one","two"]
 *   };
 *
 *   let str = 'Hi {user.name.first} {user.name.last}, your email address is {email}, and your second group is {groups[1]}'
 * 
 *   format(str, data)
 *   => returns "Hi Jane Doe, your email address is [email protected], and your second group is two"
 */

function format(str, data) {
    var varnames = {};
    function array_path(path, i) {
        var this_k = '[' + i + ']';
        if (!path.length)
            return [this_k];
        path = path.slice();
        path[path.length - 1] += this_k;
        return path;
    }
    function add_varnames(this_data, path) {
        if (this_data.constructor == Array) {
            for (var i = 0; i < this_data.length; i++)
                add_varnames(this_data[i], array_path(path, i));
        }
        else if (this_data.constructor == Object) {
            for (var k in this_data)
                add_varnames(this_data[k], path.concat(k));
        }
        else {
            var varname = '{' + path.join('.') + '}';
            varnames[varname] = String(this_data);
        }
    }
    add_varnames(data, []);
    for (var varname in varnames)
        str = str.replace(varname, varnames[varname]);
    return str;
}

Solution 18 - Javascript

My own srtipped down version of YAHOO's printf reported by PatrikAkerstrand:

function format() { 
  return [...arguments].reduce((acc, arg, idx) => 
    acc.replace(new RegExp("\\{" + (idx - 1) + "\\}", "g"), arg));
}

console.log(
  format('Confirm {1} want {0} beers', 3, 'you')
);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBlenderView Question on Stackoverflow
Solution 1 - JavascriptChristian C. SalvadóView Answer on Stackoverflow
Solution 2 - JavascriptYash MehrotraView Answer on Stackoverflow
Solution 3 - JavascriptCornflexView Answer on Stackoverflow
Solution 4 - JavascriptTomáš DivišView Answer on Stackoverflow
Solution 5 - JavascriptPatrikAkerstrandView Answer on Stackoverflow
Solution 6 - Javascriptuser113716View Answer on Stackoverflow
Solution 7 - JavascriptAphrem ThomasView Answer on Stackoverflow
Solution 8 - JavascriptRoque VianaView Answer on Stackoverflow
Solution 9 - JavascriptJames PorterView Answer on Stackoverflow
Solution 10 - JavascriptRiccardo VolpeView Answer on Stackoverflow
Solution 11 - Javascriptuser12544069View Answer on Stackoverflow
Solution 12 - JavascriptUahnbu TranView Answer on Stackoverflow
Solution 13 - Javascripttypo.plView Answer on Stackoverflow
Solution 14 - JavascriptzzzzBovView Answer on Stackoverflow
Solution 15 - Javascriptuser1114907View Answer on Stackoverflow
Solution 16 - JavascriptEmmanuel N KView Answer on Stackoverflow
Solution 17 - JavascriptmwagView Answer on Stackoverflow
Solution 18 - JavascriptneurinoView Answer on Stackoverflow