Javascript replace with $1 as var - javascript

I have the following situation:
There is a certain string that contains some vars, such as:
var string = '/page/{id}/{title}';
Now, I want to be able to replace {id} and {title} with the vars from the following array:
var arr = {'id':10, 'title':'test-page'};
I came up with this little regex:
string.replace ( /{([a-zA-Z0-9]+)}/g , '$1' );
Which, as expected, just returns this:
/page/id/title
So I tried this:
string.replace ( /{([a-zA-Z0-9]+)}/g , arr [ '$1' ] );
But that returns a
/page/undefined/undefined
Now, I understand that something like this would be possible with a loop et cetera, but it would be nice to have a one-liner for this. I am not very used to JS, so I hope that there is some function or option that I am unaware of that helps me out with this :).
Best regards!

Try something like this:
var arr = {'id':10, 'title':'test-page'};
'/page/{id}/{title}'.replace(/\{([\w\d]+?)\}/g, function(a, b) {
return arr[b] || '';
});
If you use this replace thing often I would create a String helper prototype method. For example:
String.prototype.template = function(data) {
return this.replace(/\{([\w\d]+?)\}/g, function(a, b) {
return data[b] || '';
});
};
and use it like this:
'/page/{id}/{title}'.template(arr);

According to MDN article,
Because we want to further
transform the result of the match before the final substitution is
made, we must use a function. This forces the evaluation of the match
prior to the toLowerCase() method. If we had tried to do this using
the match without a function, the toLowerCase() would have no effect.
(In the text above, replace toLowerCase() with "accessing property in object")
Then, you can use
function replacer(match, p1, p2, p3/*, ...*/, offset, string){
return arr[p1];
}
var arr = {'id':10, 'title':'test-page'};
'/page/{id}/{title}'.replace(/\{([\w\d]+?)\}/g, replacer);

Related

Possible reducer case after a map function.

I'm trying to see if array.reduce would be a better option in this case.
I'd like to return the string result instead of having to set a variable in the forEach loop.
So what I'm doing is seeing if there are any matches inside a string matching my regex. Then getting the text inside that match and replacing it with a variable I pass to it. All works great but I'd like to clean it up if I can. findReplaceTemplateString is a separate function and I'm ok with that. Its the forEach feels like I could use a reducer instead to return the completed string. But I'm new to reducers and not sure if this is a good case for it. Anyone have any thoughts on this.
const reg = /\{.+?\}/g;
const matches = tpl.match(reg);
let str = '';
matches.map(item => item.slice(1, -1)).forEach((placeHolder) => {
str = findReplace(tpl, placeHolder, props[placeHolder] || '');
});
I don't see the point of overcomplicating it. Simply use String.prototype.replace() with function as a second parameter. That will dynamically replace your pattern with valid parameters.
const input = 'Hi there, {name}! What are you doing in {city}?';
const props = {name: 'Alex', city: 'St Petersburg'};
const output = input.replace(/\{.+?\}/g, (p) => {
return props[p.slice(1, -1)] || p /* here you may use '' */;
});
console.log( output );

Replace individual symbols in a set

Is there a simplified way in JavaScript + Reg-Ex to replace all occurrences of each symbol in a set with its alternative symbol?
Example:
"Test: 1, 2, 3 and 1".replace("123", "ABC");
// we need to get: "Test: A, B, C and A";
I mean, is there any Reg-Ex trick to avoid a for-loop here? And anyway, what would be the most efficient way to do it?
Provisions:
In my task the set of symbols is usually very short (could even be 3 symbols) and it is static, not dynamic, very similar to the example shown.
Sometimes a symbol needs to be replaced with an empty '', i.e. removed.
You could build out your replacements using an Object Literal.
var map = {'1':'A', '2':'B', '3':'C'};
str = str.replace(/[123]/g, function(k) {
return map[k];
});
Or create a custom function using a map for this:
function _replace(str, map) {
var re = new RegExp('['+Object.keys(map).join('')+']','g');
return str.replace(re, function(x) { return map[x] });
}

Getting all var from a javastring function by Regular Expression

Hi I am new for Regex and trying to get below,
there is a string below in javascript,
"function(){var a; var a,b,c;}"
and I am trying to find [a,b,c] from it.
Please suggest me to get all variable declared in string, what will be regex.
A very very manipulative solution, but will serve your purpose
function uniq(value,index,self){
return self.indexOf(value) === index;
}
var str = "function(){var a; var a,b,c;}";
var ptrn = /var [^;]+/g;
var match;
var matches = []
while ( ( match = ptrn.exec(str) ) != null )
{
matches.push(match.join().split(" ")[1]);
}
console.log(matches.join(",").split(",").filter(uniq));
but if you understand this code you wont have to ever search for:
how to get unique values from js array
how matching a pattern with exec only returns the first match and we have to loop to get the rest of the values
finally adding a filter with a function.

How to use String representation of object property, operator, and value?

I'm trying to use a string value of say, "[ScheduledDate] < '11/1/2011'", and test for a bool value on an object like "item". But I can't seem to be able to figure out a way to do it successfully. I'm not wanting to use the eval function, but if it's the only way, then I guess I will have to. below is an example of the function I'm trying to use.
function _filterItem2() {
var item = { ScheduledDate: '1/1/2012' };
var filterExpression = "[ScheduledDate] < '11/1/2011'";
var result = item[filterExpression]; // This is where I'm not sure.
return result;
}
No, item[filterExpression] would just return the property named like your string.
Instead, you should store your filter expression as an object:
var filter = {
propname: "ScheduledDate",
operator: "<",
value: "1/1/2012"
};
Then get your comparison values:
var val1 = item[filter.propname],
val2 = filter.value;
and now comes the tricky part. You are right, you should not use eval. But there is no possibility to get the corresponding functions from operator names, so you will need to code them yourself. You might use a switch statement or a map like this:
var operators = {
"<": function(a,b){return a<b;},
">": function(a,b){return a>b;},
...
};
var bool = operators[filter.operator](val1, val2);

Javascript: How can I transform an array?

I have this on a javascript var: (it's a http returned data, and I don't know if it's an array or string - (how can we see that?) - Update: using typeof returned "string", so it's a string.
[{"nomeDominio":"gggg.fa"},{"nomeDominio":"rarar.fa"}]
How can we pass/transform that, into something like this:
["gggg.fa","rarar.fa"]
?
Thanks a lot,
MEM
You can figure out if is a string or an already parsed object by checking the type of your variable, e.g.:
ajax('url', function (response) {
alert(typeof response);
});
You will now figure out if it's a "string" or an Array "object".
If it's a string, you can use the JSON.parse method as #alcuadrado suggest, otherwise you can simply use the array.
Several answers suggest the use of the for-in statement to iterate over the array elements, I would discourage you to use it for that.
The for-in statement should be used to enumerate over object properties, to iterate over Arrays or Array-like objects, use a sequential loop as #Ken Redler suggests.
You should really avoid for-in for this purpose because:
The order of enumeration is not guaranteed, properties may not be visited in the numeric order.
Enumerates also inherited properties.
You can also use the Array.prototype.map method to meet your requirements:
var response = [{"nomeDominio":"gggg.fa"},{"nomeDominio":"rarar.fa"}];
var array = response.map(function (item) { return item.nomeDominio; });
// ["gggg.fa", "rarar.fa"]
This question is strongly related with this one.
I would suggest reading my answer there, as it would really help; and with a little variation, it would just work:
var responseString = '[{"nomeDominio":"gggg.fa"},{"nomeDominio":"rarar.fa"}]',
responseObject = JSON.parse(responseString),
nombresDeDominio = [];
for(var i in responseObject) {
nombresDeDominio.push(responseObject[i].nomeDominio)
}
Suerte!
Assuming your data always looks like that, you can do something like this:
var foo = [{"nomeDominio":"gggg.fa"},{"nomeDominio":"rarar.fa"}];
var newarr = [];
for ( var i=0,j=foo.length;i<j;i++ ) {
newarr.push( foo[i]['nomeDominio'] );
}
Here's a working fiddle.
function transform(array, f) {
var ret = [];
$.each(array, function(index) {
var v = f.call(this, index);
if(v) {
ret.push(v);
}
});
return ret;
}
var result = transform(
[{"nomeDominio":"gggg.fa"},{"nomeDominio":"rarar.fa"}],
function() { return this.nomeDominio; }
);
alert(result.toString());
it's a http returned data, and I don't
know if it's an array or string
It's JSON, and you can use it directly in JavaScript.
If you transform it into your array, you will lose the association key / value ; are you sure it's what you want ?
Okay, firstly to get the type of a "thing", use the "typeof" operator (note that the type of an array is an object, not 'array'!):
var a = "string";
var b = 1;
var c = new Array();
alert(typeof(a)); // string
alert(typeof(b)); // number
alert(typeof(c)); // object
To get at the values in the associative array (assuming it is one), you can just loop through it, like so:
var d = [{"nomeDominio":"gggg.fa"},{"nomeDominio":"rarar.fa"}];
d["bob"] = "alice";
d["gary"] = "stephen";
for(var key in d) {
alert(d[key]);
}

Categories