javascript create nested JSON array from array - javascript

I have this array :
myArray = [ "Id = 1", "Time = 18:40", "Topic = yyyyyyyyyyyy", "GUEST", "Role = HS", "Infos = Arizona", "Role = GS", "Infos = Arizona", "Role = GS", "Infos = Colorado", "Id = 2","Time = 11:32", "Topic = xoxo", "GUEST", "Role" = "GS", "Infos = California", "Role = CS", "Infos = Maryland", "Role = GS","Infos = Nevada" ];
I want to create a nested JSON array from it:
myJson = [
{
"Id" : "1",
"Time" : "18:40",
"Topic" : "yyyyyyyyyyyy",
"GUEST":
[
{"Role" : "HS",
"Infos" : "Arizona"},
{"Role" : "GS",
"Infos" : "Arizona"},
{"Role" : "HS",
"Infos" : "Colorado"}
]
},
{
"Id" : "2",
"Time" : "11:32",
"Topic" : "xoxo",
"GUEST":
[
{"Role" : "GS",
"Infos" : "California"},
{"Role" : "CS",
"Infos" : "Maryland"},
{"Role" : "GS",
"Infos" : "Nevada"}
]
}
]
How can I do it? tried the code below without success.
myArray = ["Id = 1","Time = 18:40","Topic = yyyyyyyyyyyy","GUEST","Role = HS","Infos = Arizona","Role = GS","Infos = Arizona","Role = GS","Infos = Colorado","Id = 2","Time = 11:32","Topic = xoxo","GUEST","Role" = "GS","Infos = California","Role = CS","Infos = Maryland","Role = GS","Infos = Nevada"];
// Declaring new object
let obj = {};
// Place to remember current level of object
let level;
myJson = [];
for (let item of this.myArray) {
// If it contains an equals
if (item.includes('=')) {
// Split it into two stings
let split = item.split('=');
let key = split[0].trim();
let val = split[1].trim();
// If we're already on a lower level like GUEST3 put it in there
if (level) {
obj[level][key] = val
} else {
// Or just place the new data at the top level
obj[key] = val
}
} else {
// If there's no equals we want to go down a layer
level = item;
myJson.push(obj[item]);
}
}
console.log("myJson : "+ JSON.stringify(myJson));

Another answer is totally right - format you are requesting is totally wrong. If it would have been just going one object deeper when you meet "GUEST" string and create new object in the output when you meet next "Id = \d+" string, you could use something like:
let process = (arr) => {
let path = [];
const data = [];
let o = data;
while (arr && arr.length) {
let item = arr.shift();
let key= null;
let value = null;
if (/Id = \d+/.test(item)) {
o = {};
data.push(o);
let pair = item.split(' = ');
o.Id = pair[1];
}
else if (item == "GUEST") {
o["GUEST"] = {};
o = o["GUEST"]
value = {};
} else {
let pair = item.split(' = ');
o[pair[0]] = pair[1];
}
}
return data;
}
However with this approach your duplicate keys will get overriden like so:
[
{
"Id": "1",
"Time": "18:40",
"Topic": "yyyyyyyyyyyy",
"GUEST": {
"Role": "GS",
"Infos": "Colorado"
}
},
{
"Id": "2",
"Time": "11:32",
"Topic": "xoxo",
"GUEST": {
"Role": "GS",
"Infos": "Nevada"
}
}
]
I think this is a good start and you can fine tune parsing GUEST part up to your liking

JSON's format is wrong.
Key-value pair array is not allowed in JSON.
Key-value pair array cannot have same name key.
Change to the following format (JSON has strict requirements on the format):
myJson = [
{
"Id" : "1",
"Time" : "18:40",
"Topic" : "yyyyyyyyyyyy",
"GUEST":
[
{
"Role" : "HS",
"Infos" : "Arizona"
},
{
"Role" : "GS",
"Infos" : "Arizona"
},
{
"Role" : "HS",
"Infos" : "Colorado"
}
]
}
]

Related

Duplicate entire array if an object of the array contains multiple comma seperated values in Javascript

I have an nested array with objects docs, which I first flatten to one level.
And I have another flat array called multiValueSelected.
Now I'd like to iterate through all objects of the flattened docs-array and check if the key is also in the multiValueSelected-array.
If so, I would like to copy the entire docs-array for every comma separated value for the specific key, copy all other objects and add the new doc to the table.
With this following approach, I'm able to iterate through all comma separated values, but how can I duplicate the entire docs-array? Thank you for your help.
Example Arrays:
docs [{"id" : "test1", "color" : "green,blue,grey", "size" : "s,m"}, {"id" : "test2", "color" : "green", "size" : "l"}...]
multiValueSelected {"color, size, ..."}
Expected result for data:
1. {"id" : "test1", "color" : "green", "size" : ""}
2. {"id" : "test1", "color" : "blue", "size" : ""}
3. {"id" : "test1", "color" : "grey", "size" : ""}
4. {"id" : "test1", "color" : "", "size" : "s"}
5. {"id" : "test1", "color" : "", "size" : "m"}
6. {"id" : "test2", "color" : "green", "size" : "l"}
Script:
function importTableau(docs, table) {
var data = [];
var importedDocs = 0;
for (var i = 0; i < docs.length; i++) {
var flatten = objectFlattenData(docs[i])
var rec = {}
for (var key in flatten) {
// var key deiines the KEY
// var flatten[key] defines the VALUE without duplicates
// var flatten defines the CURRENT DOCUMENT
if (multiValueSelected.indexOf(key) > -1) {
//console.log('key: ', key, ' flatten: ', flatten[key])
var flattenString = flatten[key];
var id = key.replace(/[^A-Za-z0-9_]+/g, '')
// handling multivalues as seperate doc per value
var properties = flattenString.split(',');
var propertiesLength = properties.length;
for (var i = 0; i < propertiesLength; i++) {
// Trim the excess whitespace.
properties[i] = properties[i].replace(/^\s*/, "").replace(/\s*$/, "");
// Get the single Value
var singleValue = properties[i]
console.log(singleValue);
rec[id] = flatten[singleValue];
data.push(rec);
}
return false;
} else {
// not selected for handling multivalues as seperate doc
var id = key.replace(/[^A-Za-z0-9_]+/g, '')
rec[id] = flatten[key];
};
};
data.push(rec);
};
table.appendRows(data);
It seems a little confusing your expected output, but maybe this is what you want?
let docs = [{
"id": "test1",
"color": "green,blue,grey",
"size": "s,m"
}, {
"id": "test2",
"color": "green",
"size": "l"
}];
let multiValueSelected = ["color", "size"];
let data = [];
for (selected_value of multiValueSelected) {
for (doc of docs) {
if (doc.hasOwnProperty(selected_value)) {
let values = doc[selected_value].split(',');
for (value of values) {
let obj = {id: doc.id};
let keys = Object.keys(doc).filter(k => !['id', selected_value].includes(k));
keys.map(k => obj[k] = '');
obj[selected_value] = value;
data.push(obj);
}
}
}
}
console.log(data)
I really have not understand the question, but if you want to have this:
Input: docs [{"id" : "test1", "color" : "green,blue,grey", "size" : "s,m"}, {"id" : "test2", "color" : "green", "size" : "l"}...]
Output: multiValueSelected ["color, size, ...", "...."]
as an output you can't have [{"color, size, ..."}] because is not a valid json, a json is a composition of key-value pair and not just only a string
You can do this:
const docs = [{"id" : "test1", "color" : "green,blue,grey", "size" : "s,m"}, {"id" : "test2", "color" : "green", "size" : "l"}...];
const multiValueSelected = [];
docs.forEach(doc => {
let currentValue = "";
Object.keys(doc).forEach(key => {
if(doc[key].split(',').length > 1)
currentValue = (currentValue === "") ? key : ", " + key;
}
if(currentValue !== "") multiValueSelected.push(currentValue);
}
if you want as output this [{"color": "green,blue,grey" , "size" : "s,m" }, {"....": "....", ....}]
const docs = [{"id" : "test1", "color" : "green,blue,grey", "size" : "s,m"}, {"id" : "test2", "color" : "green", "size" : "l"}...];
const multiValueSelected = [];
docs.forEach(doc => {
const currentValue = {};
Object.keys(doc).forEach(key => {
if(doc[key].split(',').length > 1)
currentValue[key] = doc[key];
}
if(Object.keys(currentValue).length > 0) multiValueSelected.push(currentValue);
}
please let me know if I have not responded to your question

Count data from jsonObject

i have this json object array
[{"Subject":"Maths","status:"Pass"},{"Subject":"Maths","status:"Pass"},
{"Subject":"Maths","status:"Fail"},{"Subject":"Maths","status:"Fail"},
{"Subject":"English","status:"Pass"},{"Subject":"English","status:"Fail"}]
I want to count number of pass and fail for each subject and store them in object array like
[{"Subject":"Maths","Pass":2,"Fail":2},"Subject":"English","Pass":2,"Fail":2}]
This data is coming from api also subjects can vary there can be numerous subjects .
Use reduce function and in the accumulator array check if the Subject exist. If it does not exist then create an new object and set the value of key Subject , Pass & Fail.
If it exist then update the value of Pass & Fail
let k = [{
"Subject": "Maths",
"status": "Pass"
},
{
"Subject": "Maths",
"status": "Pass"
},
{
"Subject": "Maths",
"status": "Fail"
},
{
"Subject": "Maths",
"status": "Fail"
},
{
"Subject": "English",
"status": "Fail"
},
{
"Subject": "English",
"status": "Pass"
}
]
let res = k.reduce((acc, curr) => {
let findSubjectIndex = acc.findIndex((item) => {
return item.Subject === curr.Subject;
})
if (findSubjectIndex === -1) {
let crtOb = Object.assign({}, {
Subject: curr.Subject,
Pass: curr.status === "Pass" ? 1 : 0,
Fail: curr.status === "Fail" ? 1 : 0
})
acc.push(crtOb)
} else {
console.table(acc)
acc[findSubjectIndex].Pass = acc[findSubjectIndex].Pass + (curr.status === "Pass" ? 1 : 0);
acc[findSubjectIndex].Fail = acc[findSubjectIndex].Fail + (curr.status === "Fail" ? 1 : 0);
}
return acc;
}, []);
console.log(res)
Use Array.reduce & Object.values
let arr = [{"Subject":"Maths","status":"Pass"},{"Subject":"Maths","status":"Pass"},
{"Subject":"Maths","status":"Fail"},{"Subject":"Maths","status":"Fail"},
{"Subject":"English","status":"Pass"},{"Subject":"English","status":"Fail"}];
// Create an obect with key as subject and value as desired object.
let result = Object.values(arr.reduce((a, {Subject, status}) => {
// if subject exists in object, updating object with count
if(a[Subject]) a[Subject][status] = (a[Subject][status] || 0) + 1;
// else adding a new entry for subject
else a[Subject] = {Subject, [status] : 1};
return a;
}, {}));
console.log(result);
More readable and easy to understand code for newbies like me
var jsonObject = [{"Subject":"Maths","status":"Pass"},{"Subject":"Maths","status":"Pass"},
{"Subject":"Maths","status":"Fail"},{"Subject":"Maths","status":"Fail"},
{"Subject":"English","status":"Pass"},{"Subject":"English","status":"Fail"}];
var passMathCount = 0;
var failMathCount = 0;
var passEnglishCount= 0;
var failEnglishCount = 0;
//Iterate through each object
for(var i = 0; i < jsonObject.length; i++) {
var obj = jsonObject[i];
//Check combination for respective requirements
if(obj.status == "Pass" && obj.Subject == "Maths")
passMathCount++;
else if(obj.status == "Fail" && obj.Subject == "Maths")
failMathCount++;
else if(obj.status == "Pass" && obj.Subject == "English")
passEnglishCount++;
else
failEnglishCount++;
}
//Build json object array
var jsonInstance = [{"Subject": "Maths", "pass": passMathCount, "fail":failMathCount},
{"Subject": "English", "pass": passEnglishCount, "fail":failEnglishCount}];
console.log(jsonInstance);

How to assign one variable value to new variable value in JavaScript

I trying to creating a new dynamic array. I assigned one dynamic variable value to another new variable and pushing new array. But updating last array variable value.
Code
for(let i=0;i<allItems.length;i++){
let categories = allItems[i].categories;
for(let j=0;j<categories.length;j++){
let categoryId = categories[j].id;
//console.log("categories[j].id ", categoryId);
allItems[i]['categoryId'] = categoryId;
reitems.push(allItems[i]);
}
}
My Json Value:
[{
"itemName" : "3 SS Finish Baskets",
"itemDesc" : "3 SS Finish Baskets",
"itemId" : 1,
"unitId" : 2,
"categories" : [
{
"id" : 1,
"text" : "single room"
},
{
"id" : 2,
"text" : "Foyer/Living"
}
]
},
{
....
}]
Output
[{
"itemName" : "3 SS Finish Baskets",
"categoryId " : 2
},
{
"itemName" : "3 SS Finish Baskets",
"categoryId " : 2
}]
Expecting Output
[{
"itemName" : "3 SS Finish Baskets",
"categoryId " 1
},
{
"itemName" : "3 SS Finish Baskets",
"categoryId " 2
}]
Try this code, it will work.
let allItems = data;
let reitems = [];
let n = 0;
let allItemCategory = data.categories;
for(let i=0; i<allItems.length; i++){
allItems[i].categories.forEach(element => {
console.log('element.id',element.id)
let categoryId = element.id;
var obj = {
categoryId : element.id,
itemName : allItems[i].itemName,
itemDesc : allItems[i].itemDesc
}
reitems[n] = obj;
n++;
});
}
console.log('allI new reitems ------->', reitems);
Problem with shallow copy, it is assigning reference of array.
Use angular.copy(source, destination) for deep copy.
var allItems = [{
"itemName" : "3 SS Finish Baskets",
"itemDesc" : "3 SS Finish Baskets",
"itemId" : 1,
"unitId" : 2,
"categories" : [
{
"id" : 1,
"text" : "single room"
},
{
"id" : 2,
"text" : "Foyer/Living"
}
]
}]
$scope.reitems = [];
for(let i=0;i<allItems.length;i++){
let categories = allItems[i].categories;
for(let j=0;j<categories.length;j++){
let temp = {};
angular.copy(allItems[i], temp);
temp['categoryId'] = categories[j].id;
$scope.reitems.push(temp);
}
}

Group nested array in Javascript

I have an array of data that is being used for some visualisation and is in the below format
var Dataset1 = [
{
"commentBy" : "saurabh",
"comment" : "Testing",
"datestamp" : "07/07/2017",
"weekcount" : 1
},
{
"commentBy" : "raman",
"comment" : "Planning",
"datestamp" : "07/07/2017",
"weekcount" : 1
},
{
"commentBy" : "Execution",
"comment" : "Alfa Beta",
"datestamp" : "07/07/2017",
"weekcount" : 2
},
{
"commentBy" : "Execution",
"comment" : "Zseta Gama",
"datestamp" : "07/07/2017",
"weekcount" : 2
}
]
//although i have tried writing this function but this is not giving me the desired result.
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
var groubedByTeam=groupBy(Dataset1, 'weekcount')
console.log(groubedByTeam);
I want to grouped the dataset by the weekcount so that the desired result should be like this.
[
{ "weekcount" : 1
"grouped" : [
{ "commentBy" : "saurabh",
"comment" : "Testing",
"datestamp" : "07/07/2017"
},
{
"commentBy" : "raman",
"comment" : "Planning",
"datestamp" : "07/07/2017"
}
]
}, {
"weekcount" : 2
"grouped" : [
{
"commentBy" : "Execution",
"comment" : "Alfa Beta",
"datestamp" : "07/07/2017",
},
{
"commentBy" : "Execution",
"comment" : "Zseta Gama",
"datestamp" : "07/07/2017",
}
]
}
]
const formatted = [];
Dataset1.forEach((data) => {
const { weekcount, comment, commentBy, datestamp } = data;
let obj = formatted.find((item) => item.weekcount === weekcount);
if (!obj) {
formatted.push({
weekcount,
grouped: [{
comment,
commentBy,
datestamp
}]
})
} else {
obj.grouped.push({
comment,
commentBy,
datestamp
});
}
});
const Dataset1 = [{
"commentBy": "saurabh",
"comment": "Testing",
"datestamp": "07/07/2017",
"weekcount": 1
}, {
"commentBy": "raman",
"comment": "Planning",
"datestamp": "07/07/2017",
"weekcount": 1
}, {
"commentBy": "Execution",
"comment": "Alfa Beta",
"datestamp": "07/07/2017",
"weekcount": 2
}, {
"commentBy": "Execution",
"comment": "Zseta Gama",
"datestamp": "07/07/2017",
"weekcount": 2
}];
const formatted = [];
Dataset1.forEach((data) => {
const { weekcount, comment, commentBy, datestamp } = data;
let obj = formatted.find((item) => item.weekcount === weekcount);
if (!obj) {
formatted.push({
weekcount,
grouped: [{
comment,
commentBy,
datestamp
}]
})
} else {
obj.grouped.push({
comment,
commentBy,
datestamp
});
}
});
console.log(formatted);
Here is a clean way to group the data, you should be able to figure out how to format it the way you want with this as a starting point.
grouped = {}
Dataset1.forEach(function(item, index){
if (!grouped[item.weekcount]) grouped[item.weekcount] = [];
grouped[item.weekcount].push(item);
});
grouped is an object keyed with the weekcount. If a certain weekcount doesn't exist as a key in the object, an empty array is created and then the data is pushed to it. On later iterations data with the same weekcount is added to the existing array.
You could check each weekcount from 0 to max, and filter your array. It could be something like this:
var Dataset1 = [
{
"commentBy" : "saurabh",
"comment" : "Testing",
"datestamp" : "07/07/2017",
"weekcount" : 1
},
{
"commentBy" : "raman",
"comment" : "Planning",
"datestamp" : "07/07/2017",
"weekcount" : 1
},
{
"commentBy" : "Execution",
"comment" : "Alfa Beta",
"datestamp" : "07/07/2017",
"weekcount" : 2
},
{
"commentBy" : "Execution",
"comment" : "Zseta Gama",
"datestamp" : "07/07/2017",
"weekcount" : 2
}
]
var maxWeekCount = 3;
var result = []
for(var i=0; i<maxWeekCount; i++){
var group = Dataset1.filter(obj => obj.weekcount === i)
if(group.length) {
result.push({
weekCount: i,
grouped: group
})
}
}
console.log(result)
Use a helper object, that maintains a reference to the weekcount objects, to reduce the array to the grouped structure.
var Dataset1 = [{"commentBy":"saurabh","comment":"Testing","datestamp":"07/07/2017","weekcount":1},{"commentBy":"raman","comment":"Planning","datestamp":"07/07/2017","weekcount":1},{"commentBy":"Execution","comment":"Alfa Beta","datestamp":"07/07/2017","weekcount":2},{"commentBy":"Execution","comment":"Zseta Gama","datestamp":"07/07/2017","weekcount":2}];
var helperMap = {};
var result = Dataset1.reduce(function(arr, obj) {
var current = helperMap[obj.weekcount];
if(!current) {
current = {
weekcount: obj.weekcount,
grouped: []
};
helperMap[obj.weekcount] = current;
arr.push(current);
}
current.grouped.push({
commentBy: obj.commentBy,
comment: obj.comment,
datestamp: obj.datestamp
});
return arr;
}, []);
console.log(result);
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
if(rv[x[key]] == undefined){
rv[x[key]] = {"weekcount": x[key], "grouped": []}
}
stripped = {}
for(var k in x) if(k!=key) stripped[k]=x[k]; //strip "key" property
rv[x[key]]["grouped"].push(stripped);
return rv;
}, []);
};
By stripping the "key" property, this solution works with any input without modification, so if you add/remove some properties from the input, it will still work as expected, reflecting the changes.

How to create a javascript array to send data into this json format?

I am new to this so please bear with me.
Please guide me as to how to create a javascript array which in turn gives me a json like this.
{
"MotorInsurance": [{
"Service": "Compare",
"Data": [{
"Apikey": "1234",
"Process": "Compare",
"TransactionId": "32",
"Type": "New",
"Channel": "1"
}],
"Vehicle": [{
"VehicleCode": "456",
"RTOCode": "AP12",
"RegistrationYear": "2016"
}],
"User":[{
"IPAddress": "66",
"DateTime": "12-06-2016"
}]
}]
}
I have tried this :
var formData = {};
formData['MotorInsurance'] = {};
formData['MotorInsurance']['Service'] = "Compare";
formData['MotorInsurance']['Data'] = {};
formData['MotorInsurance']['Data']['Apikey'] = '1234';
formData['MotorInsurance']['Data']['Process'] = 'Compare';
formData['MotorInsurance']['Data']['TransactionId'] = '32';
formData['MotorInsurance']['Data']['Type'] = 'New';
formData['MotorInsurance']['Data']['Channel'] = '1';
formData['MotorInsurance']['Vehicle'] = {};
formData['MotorInsurance']['Vehicle']['VehicleCode'] = '';
formData['MotorInsurance']['Vehicle']['RTOCode'] = '';
formData['MotorInsurance']['Vehicle']['RegistrationYear'] = '';
formData['MotorInsurance']['User'] = {};
formData['MotorInsurance']['User']['IPAddress'] = '66.12.5.4';
formData['MotorInsurance']['User']['DateTime'] = '12-06-2016';
Please guide me. Thanks
var formData = {};
formData['MotorInsurance'] = [{}];
formData['MotorInsurance'][0]['Service'] = "Compare";
formData['MotorInsurance'][0]['Data'] = [{}];
formData['MotorInsurance'][0]['Data'][0]['Apikey'] = '1234';
formData['MotorInsurance'][0]['Data'][0]['Process'] = 'Compare';
formData['MotorInsurance'][0]['Data'][0]['TransactionId'] = '32';
formData['MotorInsurance'][0]['Data'][0]['Type'] = 'New';
formData['MotorInsurance'][0]['Data'][0]['Channel'] = '1';
formData['MotorInsurance'][0]['Vehicle'] = [{}];
formData['MotorInsurance'][0]['Vehicle'][0]['VehicleCode'] = '';
formData['MotorInsurance'][0]['Vehicle'][0]['RTOCode'] = '';
formData['MotorInsurance'][0]['Vehicle'][0]['RegistrationYear'] = '';
formData['MotorInsurance'][0]['User'] = [{}];
formData['MotorInsurance'][0]['User'][0]['IPAddress'] = '66.12.5.4';
formData['MotorInsurance'][0]['User'][0]['DateTime'] = '12-06-2016';
document.write('<pre>' + JSON.stringify(formData, 0, 4) + '</pre>');
Your formData['MotorInsurance'] has to be an array:
formData['MotorInsurance'] = [];
Then you'll be creating everything else in the first element of this array:
formData['MotorInsurance'][0] = {};
formData['MotorInsurance'][0]['Service'] = "Compare";
The same goes for Data, Vehicule and User.
You can approach it like this: for the nested objects, populate them one by one (like the data variable below) and then when assigning to the form data, make sure you put square brackets around the variable.
vehicle = {
"VehicleCode": "456",
"RTOCode": "AP12",
"RegistrationYear": "2016"
};
user = {
"IPAddress": "66",
"DateTime": "12-06-2016"
};
data = {
"Apikey": "1234",
"Process": "Compare",
"TransactionId": "32",
"Type": "New",
"Channel": "1"
};
service = {"Service": "Compare"}
o = {"Data": [data], "Vehicle": [vehicle], "User": [user], "Service": service}
formData["MotorInsurance"] = [o]

Categories

Resources