JavaScript convert string to object contains ":" - javascript

I have the following string var xx = "website:https://google.com"; I'm trying to convert to dictionary {website:"https://google.com"} usually I use str.split(":") but here I have multi : I can use replace function but what is the best way to do that ?

const strToDictionary = kColonV => {
const tmpArray = kColonV.split(':')
const k = tmpArray.shift()
const v = tmpArray.join(':')
return {[k]:v}
}
var xx = "website:https://google.com";
strToDictionary(xx) // Object { website: "https://google.com" }
Or, perhaps just:
const toDictonary = str => { return {[str.split(':')[0]]:str.substr(str.indexOf(':')+1)} }
toDictionary(xx) // Object { website: "https://google.com" }
There's a lot of ways you could phrase this.
class Dictionary extends Object {};
const kvToDict = str => Dictionary.assign( // No need to do this, but it's interesting to explore the language.
new Dictionary(),
{[str.slice(0, str.indexOf(':'))]:str.slice(str.indexOf(':')+1)}
)
const kvDict = kvToDict("website:https://google.com")
console.log(kvDict.constructor, kvDict) // Dictionary(), { website: "https://google.com" }
I like this one:
const kvToObj = str => Object.assign(
{},
{[str.slice(0, str.indexOf(':'))]:str.slice(str.indexOf(':')+1)}
)
kvToObj("website:https://google.com") // Object { website: "https://google.com" }

You can split on the first occurrence of :.
var xx = "website:https://google.com";
xx = xx.split(/:(.+)/);
var dictionary = {[xx[0]]:xx[1]};
console.log(dictionary);

Related

How do I convert a string to a dictionary in javascript?

I have a string
var str = "1:6,5,2,2:3";
I want to convert this str into a js dictionary such that:
var dict = {1:"6,5,2",
2:"3"};
so that I can fetch the values by their respective key index. How do I convert it?
I had tried this code to store the splitted values into an array:
var pages = "1:6,5,2,2:3";
var numbers = [];
if (pages.includes(',')) {
page_nos = pages.split(',');
for (var i = 0; i < page_nos.length; i++) {
if (page_nos[i].includes(':')) {
var n = page_nos[i].split(':');
numbers.push(n[1]);
} else {
numbers.push(page_nos[i]);
}
}
} else {
page_nos = pages.split(':');
numbers.push(page_nos[1])
};
console.log('numbers: ', numbers);
But it's incorrect, as without dictionary it's impossible to know what value belongs to which index
If you cannot make your input string a proper JSON or another easily parsable format in the first place, this answers your question:
const str = "1:6,5,2,2:3";
const obj = str.split(/,(?=\d+:)/).reduce((accu, part) => {
const [k, v] = part.split(':', 2);
accu[k] = v;
return accu;
}, {});
console.log(obj);
Cut the string at all commas that are followed by digits and a colon. Each part has a key in front of a colon and a value after it, which should be stuffed in an object in this format.
No mutations solution.
const str = "1:6,5,2,2:3";
const dict = str
.split(/(\d+:.*)(?=\d+:)/g)
.reduce((t, c) => {
const [key, value] = c.replace(/,$/, "").split(/:/);
return { ...t, [key]: value }
});
console.log(dict);
if you consider not using regular expression, you might try this as well.
to take out a dict (Object) from that string, this will do.
var pages = "1:6,5,2,2:3";
function stringToObject(str) {
var page_object = {};
var last_object;
str.split(",").forEach((item) => {
if (item.includes(":")) {
page_object[item.split(":")[0]] = item.split(":")[1];
last_object = item.split(":")[0];
} else {
page_object[last_object] += `,${item}`;
}
});
return page_object;
}
console.log(stringToObject(pages))
Presented below may be one possible solution to achieve the desired objective.
NOTE:
In lieu of var the code uses either let or const as applicable.
Code Snippet
const pages = "1:6,5,2,2:3";
const resObj = {};
let page_nos, k;
if (pages.includes(',')) {
page_nos = pages.split(',');
for (let i = 0; i < page_nos.length; i++) {
if (page_nos[i].includes(':')) {
let n = page_nos[i].split(':');
k = n[0];
resObj[k] = n[1].toString();
} else {
resObj[k] += ", " + page_nos[i].toString();
}
}
} else {
page_nos = pages.split(':');
resObj[page_nos[0]] = [page_nos[1]]
numbers.push(page_nos[1])
};
console.log('result object: ', resObj);
This code essentially fixes the code given in the question. It is self-explanatory and any specific information required may be added based on questions in comments.
You could take nested splitring for entries and get an object from it.
const
str = "1:6,5,2,2:3",
result = Object.fromEntries(str
.split(/,(?=[^,]*:)/)
.map(s => s.split(':'))
);
console.log(result);

Parsing string with special character and returning the output

I know its a pretty simple question, but to anyone who is new to Javascript this can be interesting.
Is there any fastest way to parse this string and get the color for the fruit like shown below :
var fruitAndColors = "APPLE=RED&GUAVA=GREEN&STRAWBERRY=RED&BANANA=yellow&ORANGE=orange"
var applecolor = getColor("APPLE") // RED
var bananaColor = getColor("BANANA") //yellow
Here is a regex match approach:
function getColor(fruitAndColors, fruit) {
return fruitAndColors.match(new RegExp("\\b" + fruit + "=([^&]+)"))[1];
}
var fruitAndColors = "APPLE=RED&GUAVA=GREEN&STRAWBERRY=RED&BANANA=yellow&ORANGE=orange"
console.log(getColor(fruitAndColors, "APPLE")); // RED
console.log(getColor(fruitAndColors, "BANANA")); //yellow
For the case of searching for APPLE we use the following regex pattern:
\bAPPLE=([^&]+)
This places the key (the color) in the first capture group, which the helper function then returns.
Regex will probably be the best bet for this however it is definitely not my strong-suit. That said, here's what I came up with just some Javascript:
var fruitAndColors =
'APPLE=RED&GUAVA=GREEN&STRAWBERRY=RED&BANANA=yellow&ORANGE=orange';
const getColor = (key) => {
const entries = fruitAndColors.split('&').reduce((acc, val) => {
const [fruit, color] = val.split('=');
acc[fruit] = color;
return acc;
}, {});
return entries[key];
};
var appleColor = getColor('APPLE'); // RED
var bananaColor = getColor('BANANA'); //yellow
A little class that handle that kind of url parse
class UrlParse {
#objects;
constructor(uri) {
this.uri = uri
this.objects = {}
this.parse()
}
parse() {
let arr = this.uri.split('&')
for (let a of arr) {
let arr = a.split(/\=/)
this.objects[arr[0]] = arr[1]
}
}
getName(name) {
return this.objects[name]
}
}
var fruitAndColors = "APPLE=RED&GUAVA=GREEN&STRAWBERRY=RED&BANANA=yellow&ORANGE=orange"
let p = new UrlParse(fruitAndColors)
console.log(p.getName('BANANA'))
You can use a regular expression passing in the fruit, and returning the first match.
const fruitAndColors = 'APPLE=RED&GUAVA=GREEN&STRAWBERRY=RED&BANANA=yellow&ORANGE=orange';
console.log(getColor('APPLE', fruitAndColors));
console.log(getColor('GUAVA', fruitAndColors));
console.log(getColor('STRAWBERRY', fruitAndColors));
console.log(getColor('BANANA', fruitAndColors));
console.log(getColor('ORANGE', fruitAndColors));
function getColor(fruit, fruitAndColors) {
const regex = new RegExp(`${fruit}=([A-Za-z]+)`);
return fruitAndColors.match(regex)[1];
}
Why don't we just use a map instead of parsing it with regex. I think that would be more efficient.
const str = "APPLE=RED&GUAVA=GREEN&STRAWBERRY=RED&BANANA=yellow&ORANGE=orange";
const fruitColorArray = str.split("&").map((value) => value.split("="));
const fruitColorMap = new Map(fruitColorArray);
function getColor(fruit) {
return fruitColorMap.get(fruit);
}
const applecolor = getColor("APPLE"); // RED
const bananaColor = getColor("BANANA"); //yellow
console.log(applecolor, bananaColor);

JavaScript How to convert a string into a nested object

I have a response string like this:
|||COVID HPI^^^FEVER^^^Low Grade
|||COVID HPI^^^FEVER^^^Continuous
|||COVID HPI^^^RHINORRHEA/SNEEZING^^^No
|||GENERAL EXAM^^^CL^^^Conscious
|||GENERAL EXAM^^^ORIENTED^^^Yes
And i want to convert it into something like this:
{
"COVID HPI": [
{
"FEVER": "Low Grade, Continuous",
"RHINORRHEA/SNEEZING": "Yes"
}
],
"GENERAL EXAM": [
{
"CL": "Conscious",
"ORIENTED": "Yes"
}
]
}
I am not able to go beyond this without an ugly code:
const na = [];
fetch('http://localhost/test/json/newdata.json')
.then(response => {
let vv = response.json();
return vv;
})
.then(function(data){
console.log(data[0]['tRxVal'])
let nav = data[0]['tRxVal'].slice(3).split('|||');
let nbv = nav.map(function(item,i){
return item.split('^^^');
});
//console.log(nbv);
nbv.forEach(function(v,i){
if(!na.includes(v[0])){
na.push(v[0]);
}
})
console.log(na)
})
.catch(err => {
// handle errors
});
Can someone please help me with this
Thanks
You should try to use the split function.
You could do a first split on the string for "|||", after that you could split all the resulting strings for "^^^", so that you can divide keys and values.
Something like that (take it as pseudocode)
let strings = data.split("|||");
for (string in strings){
let objectKeyValue = string.split("^^^");
let object = objectKeyValue[0];
let key = objectKeyValue[1];
let value = objectKeyValue[2];
}
from here, compose your object and you're good to go.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split
Split by ||| to get each row, and then split each row by ^^^. Then, you can think of each "row" like this: <topLevelCategory>^^^<subCategory>^^^<subCategoryAnswer>. Use this mental model of each row to build your object around.
const string = `|||COVID HPI^^^FEVER^^^Low Grade
|||COVID HPI^^^FEVER^^^Continuous
|||COVID HPI^^^RHINORRHEA/SNEEZING^^^No
|||GENERAL EXAM^^^CL^^^Conscious
|||GENERAL EXAM^^^ORIENTED^^^Yes`;
function stringToObj(str) {
const branches = str.split('|||');
const obj = {};
branches.forEach((branch) => {
const leaves = branch.split('^^^');
const [top, sub, answer] = leaves;
if (top) {
if (!obj[top]) obj[top] = {};
const trimmedAnswer = answer.trim();
const curr = obj[top][sub];
if (curr) {
obj[top][sub] = `${curr}, ${trimmedAnswer}`;
} else {
obj[top][sub] = answer.trim();
}
}
});
return obj;
}
console.log(stringToObj(string));

How to get specific part of url string?

This is the result of the console.log below:
console.log('subscribe:', event.url);
"https://hooks.stripe.com/adapter/ideal/redirect/complete/src_1E2lmZHazFCzVZTmhYOsoZbg/src_client_secret_EVnN8bitF0wDIe6XGcZTThYZ?success=true"
Where I want to strip src_1E2lmZHazFCzVZTmhYOsoZbg and src_client_secret_EVnN8bitF0wDIe6XGcZTThYZ
How to achieve this?
Convert the string to a url, read the pathname and than split on / and take the last two parts.
var str = "https://hooks.stripe.com/adapter/ideal/redirect/complete/src_1E2lmZHazFCzVZTmhYOsoZbg/src_client_secret_EVnN8bitF0wDIe6XGcZTThYZ?success=true"
const parts = new URL(str).pathname.split('/').slice(-2)
console.log(parts)
If the query parameter ?success=true is optional (as in most cases is) you could
function getSrcAndSecret (url) {
const pts = /\/(src_[^/?]+)\/(src_client_secret_[^/?]+)/.exec(url);
return {
src: pts && pts[1] || "",
secret: pts && pts[2] || ""
}
}
// Demo:
const test1 = getSrcAndSecret("https://hooks.stripe.com/adapter/ideal/redirect/complete/src_1E2lmZHazFCzVZTmhYOsoZbg/src_client_secret_EVnN8bitF0wDIe6XGcZTThYZ?success=true");
const test2 = getSrcAndSecret("https://hooks.stripe.com/adapter/ideal/redirect/complete/src_1E2lmZHazFCzVZTmhYOsoZbg/src_client_secret_EVnN8bitF0wDIe6XGcZTThYZ");
const test3 = getSrcAndSecret("https://hooks.stripe.com/adapter/ideal/redirect/complete");
console.log(test1, test2, test3)
const url = "https://hooks.stripe.com/adapter/ideal/redirect/complete/src_1E2lmZHazFCzVZTmhYOsoZbg/src_client_secret_EVnN8bitF0wDIe6XGcZTThYZ?success=true";
const res = url.split(/\?|\//g).filter(el => el.startsWith("src"));
console.log(res)
const [a, b] = event.url.split("?")[0].split("/").slice(-2);

How to replace string {} value to obj (key value)

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

Categories