I have a string where the object name is separated by dot from the field name as follows:
{\"person.firstName\":\"Ahmed\",\"person.job\":\"Doctor\",\"products.packName\":\"antibiotic\",\"products.packSize\":\"large\"}}";
I want to parse it to look like the json format:
"{\"person\": {\"firstName\":\"Ahmed\",\"job\":\"Doctor\",},\"products\": {\"packName\":\"antibiotic\",\"packSize\":\"large\"}}";
Is there an efficient algorithm for that?
Maybe this is help for you.
var str='{\"person.firstName\":\"Ahmed\",\"person.job\":\"Doctor\",\"products.packName\":\"antibiotic\",\"products.packSize\":\"large\"}';
var newObj={}
var json=JSON.parse(str);
for (i in json) {
var splt=i.split('.');
var key=splt[0];
var subkey=splt[1];
if(!(key in newObj)) {
newObj[key]={};
}
newObj[key][subkey]=json[i];
}
//if you need string use str or not use newObj
var str=JSON.stringify(newObj);
console.log(str);
console.log(newObj);
console.log(newObj.person);
console.log(newObj.person.firstName);
console.log(newObj.person.job);
Assuming left side may have multiple dots
let parsedObj = JSON.parse(<..YOUR STRINGIFIED JSON..>);
let myObj = {};
Object.keys(parsedObj).forEach((key) => {
let val = parsedObj[key];
let subKeys = key.split(".");
let currentRef = myObj;
subKeys.forEach((subKey, idx) => {
if(idx === subKeys.length - 1) {
currentRef[subKey] = val;
} else {
currentRef[subKey] = currentRef[subKey] || {};
currentRef = currentRef[subKey];
}
});
});
let finalString = JSON.stringify(myObj);
P.S. Your string seems to contain an extra } in the end
Related
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);
I have a string like this:
let user = "req.user.role"
is there any way to convert this as nested objects for using in another value like this?
let converted_string = req.user.role
I know I can split the user with user.split(".")
my imagination :
let user = "req.user.role".split(".")
let converted_string = user[0].user[1].user[2]
I found the nearest answer related to my question : Create nested object from query string in Javascript
Try this
let user = "req.user.role";
let userObj = user.split('.').reduceRight((obj, next) => ({
[next]: obj
}), {});
console.log(userObj);
Or this, for old browsers
var user = "req.user.role";
var userArray = user.split('.'), userObj = {}, temp = userObj;
for (var i = 0; i < userArray.length; i++) {
temp = temp[userArray[i]] = {};
}
console.log(userObj);
The function getvalue() will return the nested property of a given global variable:
var user="req.user.role";
var req={user:{role:"admin"}};
function getvalue(str){
return str.split('.').reduce((r,c,i)=>i?r[c]:window[c], '');
}
console.log(getvalue(user));
I'll take my shot at this:
let user = "req.user.role"
const trav = (str, o) => {
const m = str.split('.')
let res = undefined
let i = 0
while (i < m.length) {
res = (res || o)[m[i]]
if (!res) break
i++
}
return res
}
const val = trav(user, {
req: {
user: {
role: "admin"
}
}
})
console.log(val)
this function will traversed the passed in object for the entire length of the provided string.split "." list returning either a value or undefined.
You can do it like this:
let userSplitted = "req.user.role".split('.');
let obj, o = obj = {};
userSplitted.forEach(key=>{o=o[key]={}});
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"));
str = "books:book1, books:book2, houses:house1, houses:house2, person:james";
I want to convert above string to separate arrays or arrays within an object, something like:
books = ["book1","book2"];
houses = ["house1","house2"];
person = ["james"];
How can I do this in JavaScript?
var string = "books:book1, books:book2, houses:house1, houses:house2, person:james";
var hash = {};
var splitByComma = string.split(',');
function addKeyByVal( key, val ){
if(!hash[key]) hash[key] = [];
hash[key].push(val);
}
for( var s in splitByComma ){
var splitByColon = splitByComma[s].split(":");
addKeyByVal(splitByColon[0], splitByColon[1]);
}
console.log(hash);
You probably want an object, with keys containing the arrays.
var str = "books:book1, books:book2, houses:house1, houses:house2, person:james";
var obj = str.split(',').reduce( (a,b) => { // split the string on comma
var parts = b.trim().split(':'); // split the parts on colon
if (! (parts[0] in a) ) a[parts[0]] = []; // if no key, create an array
a[parts[0]].push(parts[1]); // push the value to the array
return a; // return the object for next iteration
}, {})
console.log(obj)
You can split on ', ' and reduce to an object containing key: []:
const string = "books:book1, books:book2, houses:house1, houses:house2, person:james";
const output = string.split(', ').reduce((obj, cur) => {
let [category, value] = cur.split(':');
if (!Array.isArray(obj[category])) {
obj[category] = [value];
} else {
obj[category].push(value);
}
return obj;
}, {});
console.log(output);
Something like this:
var string = "books:book1, books:book2, houses:house1, houses:house2, person:james";
var books = [];
var houses = [];
var person = [];
string.split(", ").forEach(function(e) {
switch (e.split(":")[0]) {
case "books":
books.push(e.split(":")[1]);
break;
case "houses":
houses.push(e.split(":")[1]);
break;
case "person":
person.push(e.split(":")[1]);
break;
}
});
The code goes like this:
Make three new arrays for books, houses, and person.
Split the string into an array, separating by ,.
Go through each element in the new array and split it into another array, separating by :
If the string on the left is books, houses, or person then append the string on the right to the books, houses, or person arrays, respectively.
This will put create global variables for you leveraging the window, but for the love of god please don't -- just use an object. While this answer is what you asked for, the other answers are what you really want.
var str = "books:book1, books:book2, houses:house1, houses:house2, person:james";
var splitStr = str.split(',');
var i;
var key;
var val;
var temp;
for (i=0; i<splitStr.length; i++) {
temp = splitStr[i].split(':');
key = temp[0].replace(/ /g,'');
val = temp[1];
if (!window[key]) {
window[key] = [];
}
window[key].push(val);
}
console.log(books, houses, person);
First, you can use the split string method twice to break down the data, then to make them into (almost) global variables, you can set them as window properties, however this can be dangerous if the values passed interfere with the existing properties.
var pairs = str.split(", ");
for(var i = 0; i < pairs.length; i++) {
var key = pairs[i].split(":")[0];
var val = pairs[i].split(":")[1];
if(window.hasOwnProperty(key)) {
window[key].push(val);
}
else {
window[key] = [];
window[key].push(val);
}
}
This method is not recommended for cases where the source of the string is unknown, as it directly modifies window properties, some of which may cause unexpected behaviour if overwritten.
RegExp method.
var string = "books:book1, books:book2, houses:house1, houses:house2, person:james",
arr = string.split(', '), obj = {}, res = [];
arr.forEach(function(v){
var array = [],
elem1 = v.match(/\w+(?=:)/),
elem2 = v.match(/(?:)\w+/g)[1];
if (!obj[elem1]){
obj[elem1] = [];
obj[elem1].push(elem2);
} else {
obj[elem1].push(elem2);
}
});
console.log(obj);
I'm writing a piece of code in JavaScript for modern browser. I'm not using lodash or underscore as we want to keep the library as small as possible.
For example,
If the url comes like this. http://something.com/#hash=value
And the app is configured to capture key hash then the result would be this. Nothing fancy. I was just wondering if there's a better way or simple way to do this.
{
'hash': 'value'
}
The code
var config = Object.assign({}, {
capturedHashParams: ['hash']
});
var hashValue = '#hash=value1'.substr(1);
var capturedHashParams = {};
if (config.capturedHashParams && Array.isArray(config.capturedHashParams)) {
var splitedHash = hashValue.split('=');
if (splitedHash.length > 0) {
var key = splitedHash[0] || '';
var value = splitedHash[1] || '';
if (key && value) {
config.capturedHashParams.forEach(function(hp) {
if (hp.toLowerCase().indexOf(key.toLowerCase()) > -1) {
capturedHashParams[key] = value;
}
});
}
}
}
console.log(capturedHashParams);
https://jsfiddle.net/c92p0rfm/2/
i think you are watching for something like this:
var output = [];
var hashString = window.location.hash;
var hashArray = hash.split('&');
for(var index = 0; index < hashArray.length; index++){
var text = hashArray[index];
var tempArray= text.split('=');
var object = {
id: tempArray[0],
value: tempArray[1]
};
output[index] = object;
}
now output looks like this:
[
{
id: "hash",
value: "value"
}
]
Your question is somewhat ambiguous. It appears that you want to extract key/value pairs from an url hash and return as a JavaScript object. I am bit uncertain about whether you want to extract all key/value pairs or only those provided in a config object. I am also a bit uncertain as to whether you want a solution within a strict functional programming paradigm, or just a plain solution with a small code footprint. I will assume the latter.
A straightforward approach to capture all key/value pairs:
var url = 'http://something.com/#hash=value&anotherHash=value';
//extract key=value pairs from url
var params = url.split('#').pop().split('&');
//assign to data object
for(var data = {}, i = 0, temp; i < params.length; i++){
// extract array [key, value]
temp = params[i].split('=');
// assign to data object
data[temp[0]] = temp[1];
}
console.log(data);
A more compact solution to do the same with .reduce():
var url = 'http://something.com/#hash=value&anotherHash=value';
var data = url
.split('#')
.pop()
.split('&')
.reduce(function(obj, keyval){
keyval = keyval.split('=');
obj[keyval[0]] = keyval[1];
return obj;
}, {});
console.log(data)
If you want to configure which keys to extract:
var url = 'http://something.com/#hash=value&anotherHash=value¬ThisHash=value';
//config object
var keysToCapture = [
'hash',
'anotherHash'
];
var data = url
.split('#')
.pop()
.split('&')
.reduce(function(obj, keyval){
keyval = keyval.split('=');
if(keysToCapture.indexOf(keyval[0]) > -1){
obj[keyval[0]] = keyval[1];
}
return obj;
}, {});
console.log(data)
Which you could capture in a reusable function like this:
function extractParamsObject(url, keysToCapture){
return url
.split('#')
.pop() //hash/fragment: everything after the last #
.split('&')
.reduce(function(obj, keyval){
keyval = keyval.split('=');
if(keysToCapture.indexOf(keyval[0]) > -1){
obj[keyval[0]] = keyval[1];
}
return obj;
}, {});
}
console.log(extractParamsObject(
'http://something.com/#hash=value&anotherHash=value¬ThisHash=value',
['hash', 'anotherHash']
));