I recently started programming on nodeJs.
I have different strings and Json Object;
eg :
var str = 'My name is {name} and my age is {age}.';
var obj = {name : 'xyz' , age: 24};
var str = 'I live in {city} and my phone number is {number}.';
var obj = {city: 'abc' , number : '45672778282'};
How do I automate this process, so using string and obj I will replace string {} value to obj (key value).
I have tried PUG but not able to parse.
pug.render(str, obj);
Doesn't work for me.
lets see, you want to make something like templating, just like handlebars http://handlebarsjs.com/.
I will give you this example to make a simple-handlebars for you case:
function render(template, properties)
{
var result = template;
for (i in properties)
{
result = result.replace("{"+i+"}",properties[i]);
}
return result;
}
but this one will only change first occurence of respective properties, if you want you may use this for replace all in the whole template:
function render(template, properties)
{
var result = template;
for (i in properties)
{
var reg = new RegExp("{"+i+"}","g");
result = result.replace(reg,properties[i]);
}
return result;
}
Here is a variation on the theme.
var str = 'My name is {name} and {name} my age is {age}.';
var obj = {name : 'xyz' , age: 24};
var render = function (str, obj) {
return Object.keys(obj).reduce((p,c) => {
return p.split("{" + c + "}").join(obj[c])
}, str)
}
render(str, obj)
I think you should not re-invent the wheel because the easiest solution is to use some popular node modules.
I suggest 'sprintf-js'.
See my sample code here,
const sprintfJs = require('sprintf-js')
const template = 'hello %(name)s today is %(day)s'
const data = {
name: 'xxxx',
day: 'Tuesday'
}
const formattedString = sprintfJs.sprintf(template, data)
console.log(formattedString)
This is possible with single replace call.
var obj = {name : 'xyz' , age: 24};
let c_obj = {};
let wordArr = [];
const res = str.matchAll("{.*?}");
for(const match of res){
c_obj[match[0]] = obj[match[0].slice(1,-1)];
wordArr.push(match[0]);
}
let new_str = str.replace(new RegExp(wordArr.join('|'),'g'), match => c_obj[match]);
Related
I try to create an object with a value for the last key. I just have an Array with the keys and the value but dont know how it will be possible to create an object without use references in javascript.
As far as I know there isnt a way to create a reference of a variable in javascript.
This is what i have:
var value = 'test';
var keys = ['this', 'is', 'a', 'test'];
This is what i want:
myObject: {
this : {
is: {
a : {
test : 'test'
}
}
}
}
Any idea how i can do this the best way in JavaScript ?
How about this...
const value = 'test'
const keys = ['this', 'is', 'a', 'test']
const myObject = keys.reduceRight((p, c) => ({ [c]: p }), value)
console.info(myObject)
Or, if you're not a fan of object literal key shortcuts and arrow functions...
keys.reduceRight(function(p, c) {
var o = {};
o[c] = p;
return o;
}, value);
See Array.prototype.reduceRight() - Polyfill if you need IE <= 8 support.
With this:
var curObj = myObject = {};
for(var i=0; i<keys.length-1; i++)
curObj = curObj[keys[i]] = {};
curObj[value] = keys[i];
Outputs:
{
this : {
is: {
a : {
Test : 'test'
}
}
}
}
As opposed to the other answers, this outputs exactly what you asked for.
Cheers
var o={}, c=o;
var value = 'Test';
var keys = 'this is a test'.split(' ');
for (var i=0; i<keys.length-1; ++i) c = c[keys[i]] = {};
c[keys[i]] = value;
console.log(JSON.stringify(o));
// {"this":{"is":{"a":{"test":"Test"}}}}
If you want the output like
{
this : {
is: {
a : 'test'
}
}
}
Do the following
var keys = ['this', 'is', 'a', 'test'];
var output = keys.reduceRight((p,c)=>({[c]:p}))
console.log(output)
And the output will be like
{ this: { is: { a: 'test' } } }
I have a .js file which has config structure something like this.
genGetLocations:{
data_url:'restaurants/{var1}/tables/{var2},
}
THis is one example. Some might have config that has data_url which has more than two dynamic variables. Then in .vue file, after getting the data_url, i will have two ids which have to be replaced into var1 and var2 so that I will have the final rest api url to make the request to.
Problem: I don't know how many variables each data_url is going to have and where they are going to be placed in data_url. So, in .vue files, when I will have the ids, i want to replace them in data_url.
Depending on whether your IDs are in an array or an object, you could do one of the following:
const data = 'restaurants/{var1}/tables/{var2}';
const idsArray = [101, 102];
console.log(
data.replace(/\{var(\d+)\}/g, (substr, idx) => idsArray[parseInt(idx) - 1])
);
const data = 'restaurants/{var1}/tables/{var2}';
const idsObj = {
var1: 101,
var2: 102
};
console.log(
data.replace(/\{(var\d+)\}/g, (substr, key) => idsObj[key])
);
If you want the keys to be arbitrary:
const data = 'restaurants/{foo}/tables/{bar}';
const idsObj = {
foo: 101,
bar: 102
};
console.log(
data.replace(/\{(.*?)\}/g, (substr, key) => idsObj[key])
);
This is looking for every {} in your URL. So it could be {var1}, {string2} or so.
Try this:
var info = {"genGetLocations":{
"data_url" : "restaurants/{var1}/tables/{var2}"
}};
var ids = ["test1", "test2", "test3"];
var regexp = /\{.*?\}/g;
var results = info.genGetLocations.data_url.match(regexp);
var replacedString = info.genGetLocations.data_url;
results.forEach(function(result, index) {
replacedString = replacedString.replace(new RegExp(result,"g"), ids[index]);
});
console.log(replacedString);
May be you can try this
String.prototype.formatUnicorn = String.prototype.formatUnicorn || function () {
var e = this.toString();
if (!arguments.length)
return e;
var t = typeof arguments[0],
n = "string" == t || "number" == t ? Array.prototype.slice.call(arguments) : arguments[0];
for (var i in n)
e = e.replace(new RegExp("\\{" + i + "\\}", "gi"), n[i]);
return e
}
/** Lets Assume your Code
genGetLocations:{
data_url:'restaurants/{var1}/tables/{var2},
}**/
console.log('restaurants/{var1}/tables/{var2}'.formatUnicorn({'var1':'test1','var2':'test2'}))
I want to extract the variables names from a string like this: "foo=valor bar=second", and so on.
To return:
{
foo: "valor",
bar: "second",
...
}
You can use Regex Look Aheads to check for a variable name that is preceded by an = symbol
var str = "foo=valor bar=second";
var varRegex = /\w+(?=(\s)*(\=))/g;
var valueRegex = /(?<=(\=)[\s'"]*)\w+/g;
var varArr = str.match(varRegex);
var valueArr = str.match(valueRegex);
console.log(valueArr);
let obj = {};
for(let i in varArr) {
obj[varArr[i]] = valueArr[i];
}
console.log(obj);
var str = "foo=valor,bar=second";
var obj = {};
str.split(",").forEach(
function(item){
if(item){
var vars = item.split("=");
obj[vars[0]] = vars[1]
}
});
console.log(obj)
Different approach from the previous answer: You can split the string on spaces and then map the result array, splitting on the equal sign to create your object (left side is property, right side is value)
If you need it your specific format you can reduce it to convert the array into one big object with all the values
let a = "foo=valor bar=second"
console.log(a.split(' ').map((i,v) => { return JSON.parse(`{"${i.split('=')[0]}": "${i.split('=')[1]}"}`);}))
let b = a.split(' ').map((i,v) => { return JSON.parse(`{"${i.split('=')[0]}": "${i.split('=')[1]}"}`);})
console.log(b.reduce(function(acc, x) {
for (var key in x) acc[key] = x[key];
return acc;
}));
Not necessarily the quickest answer (in terms of speed of submission), but less regular expressions to maintain and less variables to store.
function toJSON(str) {
const regex = /(\w+)\=(\w+)\s*/g;
let result = {};
let match;
while (match = regex.exec(str)) {
result[match[1]] = match[2];
}
return result;
}
console.log(toJSON("foo=valor bar=second"));
Here is my requirement. I was able to achieve to some level in java but we need to move it to typescript (client side).
Note: The below input is for example purpose and may vary dynamically.
Input
var input = ["a.name", "a.type", "b.city.name" , "b.city.zip", "b.desc","c"];
We need to create an utility function that takes above input and returns output as below.
Output:
Should be string not an object or anything else.
"{ a { name, type }, b { city {name, zip } , desc }, c }"
any help is much appreciated.
I don't see that typescript plays any role in your question, but here's a solution for constructing the string you requested. I first turn the array into an object with those properties, then have a function which can turn an object into a string formatted like you have
const input = ["a.name", "a.type", "b.city.name" , "b.city.zip", "b.desc","c"];
const arrayToObject = (arr) => {
return arr.reduce((result, val) => {
const path = val.split('.');
let obj = result;
path.forEach(key => {
obj[key] = obj[key] || {};
obj = obj[key];
});
return result;
}, {});
}
const objectToString = (obj, name = '') => {
const keys = Object.keys(obj);
if (keys.length === 0) {
return name;
}
return `${name} { ${keys.map(k => objectToString(obj[k], k)).join(', ')} }`;
}
const arrayToString = arr => objectToString(arrayToObject(arr));
console.log(arrayToString(input));
Here's another variation. Trick is to parse the strings recursively and store the intermediate results in an Object.
function dotStringToObject(remainder, parent) {
if (remainder.indexOf('.') === -1) {
return parent[remainder] = true
} else {
var subs = remainder.split('.');
dotStringToObject(subs.slice(1).join('.'), (parent[subs[0]] || (parent[subs[0]] = {})))
}
}
var output = {};
["a.name", "a.type", "b.city.name" , "b.city.zip", "b.desc","c"].forEach(function(entry) {
dotStringToObject(entry, output)
});
var res = JSON.stringify(output).replace(/\"/gi, ' ').replace(/\:|true/gi, '').replace(/\s,\s/gi, ', ');
console.log(res)
// Prints: { a { name, type }, b { city { name, zip }, desc }, c }
You could do something like this:
var input = ["a.name", "a.type", "b.city.name" , "b.city.zip", "b.desc","c"];
var output = {};
for(var i =0; i < input.length; i+=2){
output[String.fromCharCode(i+97)] = {};
output[String.fromCharCode(i+97)].name = input[i];
output[String.fromCharCode(i+97)].type = input[i+1];
}
console.log(JSON.stringify(output));
i have data in
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
i want the result as
Name: John
Employee Id: 2
Salary: $8000
Address: London
is it possible with split() function in javascript?
You can do it with String.split() but in this case it's simpler to use String.replace():
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
description = description.replace(/;/g, '\n').replace(/:/g, ': ');
/*
"Name: John
EmployeeID: 2
Salary: $8000
Address: London"
*/
If you want the result as an object, try:
var f = function (str) {
var x = {}, key2label = { EmployeeID: 'Employee Id' };
str.replace(/(.+?):(.+?)(;|$)/g, function (match, key, value) {
key = key2label[key] || key;
x[key] = value;
});
return x;
};
If a simple string is needed, but you still need to replace keys:
var f2 = function (str) {
var key2label = { EmployeeID: 'Employee Id' };
return str.replace(/(.+?):(.+?)(;|$)/g, function (match, key, value, semi) {
key = key2label[key] || key;
return key + ': ' + value + (semi ? '\n' : '');
});
};
If you really didn't mean to replace keys, this will do it:
var f3 = function (str) {
return str.split(':').join(': ').split(';').join('\n');
};
... or use Matt Ball's answer.
With this statement:
var arrDescription = description.split(";");
you will get an array with all the values. For more info on split check the following link.
you can even join them afterwards :
printf(arrDescription.join(" "));
For more info on join check the following link.
Max
You can probable try like this to display.
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London";
var arr=new Array();
arr=description.split(";");
for(var i=0;i<arr.length;i++)
document.writeln("<h4>"+arr[i]+"</h4>");
Yes.
You first should split on the semicolon ;. Loop through those results, and split each result on each colon :.
You will have to build the result by hand.
var description="Name:John;EmployeeID:2;Salary:$8000;Address:London"; var splitted = description.split(";");
for(var i = 0; i < splitted.length; i++) { document.write(splitted[i] + ""); }