Javascript - convert string to associative array and summarize by value - javascript

This is the first time I am working with javascript. I have the following string:
document.write(str)
[{"company":1,"number_employees":5},
{"company":4,"number_employees":25},
{"company":5,"number_employees":5},
{"company":2,"number_employees":5},
{"company":4,"number_employees":25}]
I need to convert this string such that I summarize them according to the number_employees as follows:
Three companies have number_employees=5 and two companies have number_employees=25
I am currently struggling to convert the string into javascript object. Once I have the asscoiative array, I can convert it into map and count the number_employees.
s_obj = eval('({' + messageBody + '})');
var result = s_obj.reduce(function(map, obj) {
map[obj.key] = obj.val;
return map;
}, {});
This is giving me the following error:
VM181:1 Uncaught SyntaxError: Unexpected token ,
at onMessage ((index):41)
at WebSocket.<anonymous> (stomp.min.js:8)
Any help/hint/guidance would be much appreciated!

Making a couple of assumptions about your data, you might try something like this:
First, convert the JSON string into an Object using the JSON Object, then as you were attempting use Array.prototype.reduce to summarize - (you have the arguments reversed)
var summary = {};
var messageBody = '[{"company":1,"number_employees":5},{"company":4,"number_employees":25},{"company":5,"number_employees":5},{"company":2,"number_employees":5},{"company":4,"number_employees":25}]';
JSON.parse(messageBody).reduce( (acc, cur) => {
acc[cur.number_employees] = (acc[cur.number_employees] || 0) + 1;
return acc;
}, summary);
for(entry of Object.keys(summary)) {
if (summary.hasOwnProperty(entry)) {
console.log(`There are ${summary[entry]} companies with ${entry} employees`);
}
}

Related

How to modify a JSON to a particular SQL query format in javascript?

I have a requirement to modify a JSON to a JSON having the values in a SQL query format. To better explain.
{
"Assets": {
"ASSOCIATES_NAME": ["David", "Philip"],
"CAR_NAME": ["Verron"]
}
, "Product":{"SELLER_NAME": ["XXXXX"]}
}
The result should be having the json values as an sql query leaving the keys as it is. So the resulting query will be:
{
Assets: "(ASSOCIATES_NAME = 'David' OR ASSOCIATES_NAME = 'Philip') AND CAR_NAME = 'Verron'",
Product: "SELLER_NAME = 'XXXXX'"
}
I tried something but I couldn't figure it out well. Below it is:
console.log(Object.entries(a).map(x => {return {
[x[0]]: `${Object.keys(x[1])} = '${Object.values(x[1])}'`,
}}))
However I still need to figure out how to group individual values of an array. Any elegant ES6 based solution to this?. Please folks help me out on this. TIA
Here's one way to do it, using Array.reduce to iterate over the outer object properties and Array.map over the inner object properties to generate the OR and AND expressions:
const json = `{
"Assets": {
"ASSOCIATES_NAME": ["David", "Philip"],
"CAR_NAME": ["Verron"]
}
, "Product":{"SELLER_NAME": ["XXXXX"]}
}`
const params = JSON.parse(json);
const whereItems = Object.entries(params)
.reduce((c, [k, v]) => {
c[k] = Object.entries(v)
.map(([param, value]) => '(' + value.map(v => param + " = '" + v + "'").join(' OR ') + ')')
.join(' AND ');
return c;
}, {});
console.log(whereItems);
Note that it does produce unnecessary () around the single comparisons (e.g. (SELLER_NAME = 'XXXXX')), if you really want to get rid of them just condition the addition of those characters on value.length > 1.
upvote for #nik's answer,
here is just another way for beginners.
f3 = function(key, arr){
var result = arr.map(function(e) {
return(`${key}='${e}'`)
})
if(result.length > 1)
return(`(${result.join(' AND ')})`)
else
return(result)
}
f2 = function(json) {
var result = []
for(const key in json) {
result.push(f3(key, json[key]))
}
return(result.join(' OR '))
}
f = function(json) {
var result = {}
for(const key in json) {
result[key] = f2(json[key])
}
return(result)
}
call f over your json

Nested array formation with string in javascript

I have a string as "a.b.c.d:50" so i want to form an array with the above string as t[a][b][c][d]=50. so i have tried to split the code and form but this length of n values will generate dynamically. please let me know how we can achieve this.for fixed arrays i tried as below but not able to make this as for n number of arrays.
var str1="a.b.c.d:50";
var str=str1.split(":");
var dump=str[0].split(".");
t[dump[0]][dump[1]][dump[2]][dump[3]]=dump[4]
then result will be t[a][b][c][d]=50
You could take the JSON string, parse it and iterate all key/value pairs for a nested structure by saving the last key and crate new objects if not exist and assign the vlaue with the last property.
function setValue(object, path, value) {
var last = path.pop();
path.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
}
var json = '{"subscriber.userTier.segment": "Red"}',
object = {};
Object
.entries(JSON.parse(json))
.forEach(([keys, value]) => setValue(object, keys.split('.'), value));
console.log(object);
Are you able to use ES6? This is something I just wrote quickly
var t = {a:{b:{c:{d:0}}}};
var str = "a.b.c.d:50"
var [chain, value] = str.split(':')
var parts = chain.split('.');
parts.slice(0, -1).reduce((c, v) => c[v], t)[parts[parts.length - 1]] = value;
console.log(t.a.b.c.d); // logs "50"
It works, however there is no error handling. If t['a']['b'] is undefined for example then you will get an uncaught TypeError, also if the string is in the incorrect format etc, it won't work.
At it's heart it uses reduce on the array ['a', 'b', 'c']. We pass t as the initial value for the reducer and then for each item in the array it does currentValue = currentValue[nextPart]. This will get you the object c, we then look at the last value in the parts array and set that property currentValue[lastPart] = value
That's a brief overview, hopefully you understand the rest of what's going on. If not feel free to ask :)
Quick and Dirty way of converting a string to a JSON object, if the string is constructed as a valid object.
var str = "a.b.c.d:50";
str = str.replace(/([a-z]){1}/gi, "\"$1\"");
str.split(".").forEach(function (value) {
str = str.replace(/\.(.*?)$/, ":{$1}");
});
var ar = JSON.parse("{"+str+"}");
console.log(ar);

Javascript: Convert a JSON string into ES6 map or other to preserve the order of keys

Is there a native (built in) in ES6 (or subsequent versions), Javascript or in TypeScript method to convert a JSON string to ES6 map OR a self-made parser to be implemented is the option? The goal is to preserve the order of the keys of the JSON string-encoded object.
Note: I deliberately don't use the word "parse" to avoid converting a JSON string first to ECMA script / JavaScript object which by definition has no order of its keys.
For example:
{"b": "bar", "a": "foo" } // <-- This is how the JSON string looks
I need:
{ b: "bar", a: "foo" } // <-- desired (map version of it)
UPDATE
https://jsbin.com/kiqeneluzi/1/edit?js,console
The only thing that I do differently is to get the keys with regex to maintain the order
let j = "{\"b\": \"bar\", \"a\": \"foo\", \"1\": \"value\"}"
let js = JSON.parse(j)
// Get the keys and maintain the order
let myRegex = /\"([^"]+)":/g;
let keys = []
while ((m = myRegex.exec(j)) !== null) {
keys.push(m[1])
}
// Transform each key to an object
let res = keys.reduce(function (acc, curr) {
acc.push({
[curr]: js[curr]
});
return acc
}, []);
console.log(res)
ORIGINAL
If I understand what you're trying to achieve for option 2. Here's what I came up with.
https://jsbin.com/pocisocoya/1/edit?js,console
let j = "{\"b\": \"bar\", \"a\": \"foo\"}"
let js = JSON.parse(j)
let res = Object.keys(js).reduce(function (acc, curr) {
acc.push({
[curr]: js[curr]
});
return acc
}, []);
console.log(res)
Basically get all the keys of the object, and then reduce it. What the reducer function convert each keys to an object
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
More details : http://2ality.com/2015/08/es6-map-json.html
use for in loop
let map = new Map();
let jsonObj = {a:'a',b:'b',c:'c'}
for (let i in jsonObj){
map.set(i,jsonObj[i]);
}
btw, i saw the comment below and i think map is not ordered because you use key to achieve data in map, not the index.

jsonify an array of strings

I have an array in my database that is being stored in the following format
["size:medium","height:10cm"]
this is problematic to display in a table.
Is there any way that I can convert this into a Javascript object or a JSON string like this?
{"size":"medium","height":"10cm"
}
p.s:i know json.stringfy,json_encode.the thing is they have stored key value pair as one string
You can build an object with the elements of the array and the left part as key and the right part as value of the by : separated strings.
array object
--------------------------- ---------------------------
[ -> {
"size:medium", -> size: "medium",
"height:10cm" -> height: "10cm"
] -> }
var array = ["size:medium", "height:10cm"],
object = array.reduce(function (r, a) {
var t = a.split(':');
r[t[0]] = t[1];
return r;
}, {});
document.write('<pre>' + JSON.stringify(object, 0, 4) + '</pre>');
You can try something like this:
Note: Following code will make array of objects. I don't think {["size:medium", "height:10cm"]} is a valid object
(function() {
var styleArr = ["size:medium", "height:10cm", "font-size: 18px"];
var resultObject = {};
styleArr.forEach(function(item) {
var values = item.replace(/\"/g, '').split(':');
resultObject[values[0]] = values[1];
});
console.log(resultObject)
})()
In Javascript you can use JSON.parse(), in order to convert your array in Javascript Object.
In PHP Use : json_encode(text)
In JavaScript : JSON.parse(text)

How to convert a array containing object string to regular key object pair?

I am trying to convert my uri to object value, as a success level i converted and splited in to array values with colon. But i am not able to onvert those to regular object. any one suggest me a good way. I am suing underscorejs with me.
here is my code :
var ar = ["id:1231", "currency:GBP"];
var outPut = _.map(ar, function(item){
return '{' + item + '}';
})
console.log(outPut); //consoles as ["{id:1231}", "{currency:GBP}"]
how can i get result like this:
var object = {id:1231, currency:GBP}
is underscore has any in build method for this?
There are several ways you could go about this, and Underscore offers helpers for them.
One way would be to use _.reduce to incrementally add key/value pairs to an initially empty "result" object:
var obj = _.reduce(ar, function(result, item) {
var keyAndValue = item.split(":");
result[keyAndValue[0]] = keyAndValue[1];
return result;
}, {});
Note that you can do the same without Underscore unless you have to support IE 8 or earlier.
Without any third part library:
var output = {} ;
var ar = ["id:1231", "currency:GBP"];
ar.forEach(function (item) {
var values = item.split(':') ;
output[values[0]] = values[1] ;
}) ;
Output console.log(output):
Object {id: "1231", currency: "GBP"}
Here is another version using jQuery:
var newObj = {};
$.each( ar, function( i, v ) {
var kv = v.split( ":" );
newObj[ kv[0] ] = kv[ 1 ];
});
// newObj = {id:"1231", currency:"GBP"}

Categories

Resources