Replace each element of the array in String.replace - javascript

I need to replace all characters of an incoming string with the corresponding ones from an object, how can I do this using an array?
function handleCyrillic(str) {
const obj = {
й: "\\'e9",
ц: "\\'f6",
};
let res = "";
const arr = Object.keys(obj);
arr.forEach((item) => {
const regex = new RegExp(item, "gi");
res += str.replace(regex, function (s) {
return s
.split("")
.map((n) => (n = obj[n]))
.join("");
});
});
return res;
}
console.log(handleCyrillic("цй йй!!"));
I get in the console ц\'e9 \'e9\'e9!!\'f6й йй!!
I expected \'f6\'e9 \'e9\'e9!!

The problem is that res variable is being overwritten each time a character is replaced instead of appending the replacement to the result. This is updated and a bit refactored version:
function handleCyrillic(str) {
const obj = {
й: "\\'e9",
ц: "\\'f6",
};
let res = str;
Object.keys(obj).forEach((key) => {
const regex = new RegExp(key, "gi");
res = res.replace(regex, obj[key]);
});
return res;
}

You just need to join your obj keys and surround with square brackets for the or condition and in the replace method callback replaces the match string with the corresponding replacement in the obj.
function handleCyrillic(str) {
const obj = {
й: "\\'e9",
ц: "\\'f6",
};
const arr = Object.keys(obj);
const regex = new RegExp(`[${arr.join()}]`, "gi");
return str.replace(regex, function(s) {
return obj[s]
});
}
console.log(handleCyrillic("цй йй!!"));

In your code you are replacing on the str which is parameter which never going to be change and you are concate that into the res which is function return variable that's why you are not getting desired output
function handleCyrillic(str) {
const obj = {
й: "\\'e9",
ц: "\\'f6",
};
let res = str;
const arr = Object.keys(obj);
arr.forEach((item) => {
const regex = new RegExp(item, "gi");
res = res.replace(regex,obj[item]);
});
return res;
}
console.log(handleCyrillic("цй йй!!"));

Try this. At first split the string. If a character exists as a key in the obj, map() returns the obj value, if not it returns the current character. In the end join the string.
function handleCyrillic(str) {
const obj = {
й: "\\'e9",
ц: "\\'f6",
};
return str.split('').map(char => obj[char] || char).join('');
}
console.log(handleCyrillic("цй йй!!"));

There is no need for a regular expression here. You can use Array.from with its callback:
const obj = {
й: "\\'e9",
ц: "\\'f6",
};
const handleCyrillic = str => Array.from(str, ch => obj[ch] ?? ch).join("");
console.log(handleCyrillic("цй йй!!"));
The ?? operator deals with cases where there is no mapping for a character. This still allows a mapping to the empty string to be included in obj, which means you want to remove a character.

There's no need for this conversion table in the first place. Basic Unicode Cyrillic is continuous in range 410...44f and Win-1251 is c0..ff, so you can just do some codepoint arithmetics to convert between both:
function handleCyrillic(str) {
let res = ''
for (let chr of str) {
let cp = chr.codePointAt(0)
if (0x410 <= cp && cp <= 0x44f)
res += "\\'" + (cp - 0x410 + 0xc0).toString(16)
else
res += chr
}
return res;
}
console.log(handleCyrillic("цй йй!!"));

Related

How to replace string only if the replacement exists in the target object?

I have the following snippet from this post, this code replaces the token $ENV[accountsDomain] in a string with the key from item object accountsDomain: 'www.yahoo.com' and similarly for accountsUrl
how can I run replace conditionally, replace the string only if item[g1] exists, as these keys are optional
const item = {
accountsUrl: 'www.google.com',
accountsDomain: 'www.yahoo.com'
}
const regex = /\$ENV\[(\w+)]/
let s = "foo$ENV[accountsDomain]bar";
s = s.replace(regex, (m, g1) => item[g1] || m);
console.log(s);
You cannot do that in replace, you have to do it outside.
const item = {
accountsUrl: 'www.google.com',
accountsDomain: 'www.yahoo.com'
}
function replaceItem(item, key) {
const regex = /\$ENV\[(\w+)]/
let s = `foo$ENV[${key}]bar`;
let [, match] = s.match(regex);
return item[match] && s.replace(regex, (m, g1) => item[g1]);
}
console.log('result with existing key:', replaceItem(item, 'accountsDomain'))
console.log('result with un-existing key:', replaceItem(item, 'accDomain'))

Convert string with ampersands into a key value map in Javascript (node js)

I have a string that has parameters separated with ampersands , for example :
orderid=55e3a83e&DealId=545435&Amount=590 ....
How can I convert that into a Key/Value Map ?
My current code is as follows :
const text = "orderid=55e3a83e&DealId=545435&Amount=590 ...."
let _key = "";
let _value = "";
var myregexp = /([^&=]+)=(.*?)(?=&[^&=]+=|$)/g;
var match = myregexp.exec(text);
while (match != null && key !== "url") {
_key = match[1];
_value = match[2];
dict.push({
key: _key,
value: _value
});
match = myregexp.exec(subject);
}
But it's too long , any idea for something better or shorter ?
You can split first by & and then split each element by =, and build a key/value pair
let mapper = (str) => str.split('&').filter(Boolean).map(v => {
let [key, value] = v.split('=')
return { key, value }
})
console.log(mapper('orderid=55e3a83e&DealId=545435&Amount=590 '))
In case desired output in the form of a single object
let mapper = (str) => {
let splitted = str.split('&').map(v => v && v.split('=')).filter(Boolean)
return Object.fromEntries(splitted)
}
console.log(mapper('orderid=55e3a83e&DealId=545435&Amount=590 '))
I've always used some code very similar to your current solution:
function getUrlParams(input) {
var params = {};
input.replace(/[?&]+([^=&]+)=([^&]*)/g, (m, key, value) => {
params[key] = value;
});
return params;
}
Of course, this doesn't ignore the URL parameter, and it returns a plain JS object... but you get the idea.
The string looks like a URL query, you can use URLSearchParams to parse it, here is an example:
const usp = new URLSearchParams('orderid=55e3a83e&DealId=545435&Amount=590');
const dictionary = [];
for (const [key, value] of usp.entries()) {
dictionary.push({ key, value})
}
console.log(dictionary);

Convert string into key-value pairs in an array

I have a string:
var rrule = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
I want to convert this string to key-> value pairs in an array.
[
dtstart: 20190514T111500Z,
freq: daily,
interval: 1
]
I know I can take the string and split it based on the semicolon:
var array = rrule.split(";");
... but this leaves me with an array like this:
[
"DTSTART=20190514T111500Z",
"FREQ=DAILY",
"INTERVAL=1"
]
I guess I need another step to map out the keys/values, but I get lost at this point.
Ideally, for the string I want to be able to easily access what dtstarts equals, what interval equals, what other variables equal and so on.
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
let obj = {};
for (let entry of str.split(";")) {
let pair = entry.split("=");
obj[pair[0]] = pair[1];
}
console.log(obj);
You already know how to split on the ; to get an array, from there you can just aggregate (using reduce) to get an object:
var rrule = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
var result = rrule.split(";").reduce( (obj,item) => {
let [key,value] = item.split("=");
obj[key] = value;
return obj;
},{});
console.log(result["DTSTART"])
console.log(result["FREQ"])
console.log(result["INTERVAL"])
You were correct to start with split first, this would then return you an array of strings.
To easily convert them, just use map, to return the split the single strings once more, and then return an object based on the property name you would like to give it and it's value
function createKeyValuePairFromString( str ) {
return str.split(';').map( item => {
const splitted = item.split('=');
return { [splitted[0]]: splitted[1] };
});
}
console.log( createKeyValuePairFromString("DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1") );
Use array created and split it again with =
function convertToObject(cookieString) {
const cookieObj = {};
if (!cookieString && typeof cookieString !== 'string') return cookieObj;
const arr = cookieString.split(';');
arr.forEach(record => {
if (record.includes('=')) {
const [key, value] = record.split('=');
cookieObj[key.trim()] = value;
}
});
return cookieObj;
}
You can use it like the code below:
var rrule = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
let finalObj = {};
rrule.split(';').forEach(i => finalObj[i.split('=')[0]] = i.split('=')[1]);
console.log('finalObj',finalObj);
Here I'm first splitting with ';' so consider the first item to be DTSTART=20190514T111500Z Then on splitting with = I get finalObject['DTSTART'] = 20190514T111500Z
Using forEach()
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
let obj = {};
let strArr = str.split(';')
strArr.forEach((str) => {
let [key, value] = str.split('=')
obj[key] = value;
});
console.log(obj);
Here's a fairly simple version, returning an object, not an array:
const toObj = str => str
.split (';')
.map ( s => s .split ('=') )
.reduce ( (a, [k, v]) => ({...a, [k]: v}), {} )
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
console.log (
toObj(str)
)
One of the reasons I like the library is that we can write this sort of logic more simply. In Ramda (disclaimer: I'm one of the authors), it might look like this:
const toObj = pipe ( split (';'), map (split ('=') ), fromPairs)
let str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
console.log (
toObj(str)
)
<script src="https://bundle.run/ramda#0.26.1"></script><script>
const {pipe, split, map, fromPairs} = ramda; </script>
var str = "DTSTART=20190514T111500Z;FREQ=DAILY;INTERVAL=1";
// string splitting rule
const rule = (string, delimiter) => string.split(delimiter);
const result = rule(str, ';').reduce((acc, s) => {
const [key, value] = rule(s, '=');
acc[key] = value;
return acc;
}, {});
console.log(result);

what is the best way to extract variables with '=' from a string in javascript

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"));

How to convert the string to object in JavaScript?

I need to convert this string into object
var str = "res=[xyz=name,abc=address]";
I need below output :
var obj = {xyz: "name",abc:"address"}
I tried to convert this by using json.parse and split but I can't get the result .can anyone help to do this ?
This code works with the string given. It is also very readable for noobs
var str = "res=[xyz=name,abc=address]";
str = str.split("res=")[1]
.replace("[",'{"')
.replace("]",'"}')
.replace(/=/g,'":"')
.replace(/,/g,'","');
res = JSON.parse(str);
console.log(str,"\n",res);
One more Implementation:
//str format "res=[xyz=name,abc=address]"
function stringToObject(str){
const extractedStr = str.substring(str.indexOf("[")+1,str.indexOf("]")-1);
return extractedStr.split(",").reduce((acc,keyVal)=>{
acc[keyVal.split("=")[0]] = keyVal.split("=")[1];
return acc;
},{});
}
console.log(stringToObject("res=[xyz=name,abc=address]"));
Here's a way to do it:
// format your input like this, comma separated, and key=val
const str = "xyz=name,abc=address"
const obj = str.split(',').reduce((acc, keyVal) => {
const [key, val] = keyVal.split('=')
acc[key] = val
return acc
}, {})
console.log(obj)
// { xyz: "name", abc: "address" }
Another implementation
let str = "res=[xyz=name,abc=address]";
let convertStrToObject = (str) => {
return str
.substring(5, str.length - 1)
.split(",")
.reduce((acc, item) => {
acc[item.split("=")[0]] = item.split("=")[1];
return acc;
}, {});
};
console.log(convertStrToObject(str));

Categories