Nested Array count and restructure - javascript

The Object returns users data with test results (pass, fail or Not-taken) based on their places. Trying to convert below object to something like this.
1st request
place_A
totalUsers = 2,pass = 1 (50%),fail = 1(50%), NotTaken = 0(0%)
place_B
totalUsers = 3,pass = 1(33.3%),fail = 1(33.3%), NotTaken = 1(33.3%)
others
totalUsers = 1,pass = 1(100%),fail = 0(0%), NotTaken = 0(0%)
2nd Request (can someone help to get this.)
place_A
totalUsers = 2,pass = 1 (50%),fail = 1(50%), NotTaken = 0(0%), name = place_A, items = objects(data of 2 users)
place_B
totalUsers = 3,pass = 1(33.3%),fail = 1(33.3%), NotTaken = 1(33.3%), name = place_B, items = objects(data of 3 users)
others
totalUsers = 1,pass = 1(100%),fail = 0(0%), NotTaken = 0(0%), name = others, items = objects(data of 1 user)
{
"place_A": [
{
"employeeId": "1",
"department": "A",
"place": "place_A",
"status": "Pass",
"score": 12
},
{
"employeeId": "10",
"department": "B",
"place": "place_A",
"status": "Fail",
"score": 02
}
],
"place_B": [
{
"employeeId": "2",
"department": "place_B_Dept_A",
"place": "place_B",
"status": "Pass",
"score": 20
},
{
"employeeId": "3",
"department": "place_B_Dept_B",
"place": "place_B",
"status": "fail",
"score": 05
},
{
"employeeId": "4",
"department": "place_B_Dept_B",
"place": "place_B",
"status": "",
"score": 0
}
],
"": [
{
"employeeId": "6",
"department": "someOtherDept",
"place": null,
"status": "Pass",
"score": 20,
}
]
}
I tried to make changes to the result of #decpk by adding items and name but only the first item is being added not all. Help please.
const temp = { totalUsers: 0, pass: 0, fail: 0, notTaken: 0, items :{}, name:""}
obj[curr].forEach(obj => {
temp.name = obj.place;
temp.items = obj;
})

You can easily achive this result using reduce and forEach.
const obj = {
"place_A": [
{
"employeeId": "1",
"department": "A",
"place": "place_A",
"status": "Pass",
"score": 12
},
{
"employeeId": "10",
"department": "B",
"place": "place_A",
"status": "Fail",
"score": 02
}
],
"place_B": [
{
"employeeId": "2",
"department": "place_B_Dept_A",
"place": "place_B",
"status": "Pass",
"score": 20
},
{
"employeeId": "3",
"department": "place_B_Dept_B",
"place": "place_B",
"status": "fail",
"score": 05
},
{
"employeeId": "4",
"department": "place_B_Dept_B",
"place": "place_B",
"status": "",
"score": 0
}
],
"": [
{
"employeeId": "6",
"department": "someOtherDept",
"place": null,
"status": "Pass",
"score": 20,
}
]
}
const result = Object.keys(obj).reduce((acc, curr) => {
const temp = { totalUsers: 0, pass: 0, fail: 0, notTaken: 0}
obj[curr].forEach(obj => {
temp.totalUsers += 1;
temp[obj.status.toLowerCase() || "notTaken"] += 1;
})
acc[curr || "others"] = temp;
return acc;
}, {});
console.log(result);

Related

Preparing JSON tree structure from a JSON javascript

am looking for a JSON tree from a plain JSON.
below is the Input and expected output json.
the input json doesnt have any order
There can be multiple items at each level and each item can have n number of childrens.
leafFlag = 0 means no children
leafFlag = 1 means has chidlren
path is the property which tells where the item will be placed
The expectedOutputJson needs to be placed in a table to display level wise data
var inputJson = [
{
"level": "1",
"leafFlag": "1",
"path":"p123",
"name":"food"
},
{
"level": "1",
"leafFlag": "1",
"path":"r125",
"name":"car"
},
{
"level": "2",
"leafFlag": "0",
"path":"p123/p345",
"name":"apple"
},
{
"level": "2",
"leafFlag": "1",
"path":"p123/p095",
"name":"banana"
},
{
"level": "3",
"leafFlag": "0",
"path":"p123/p095/p546",
"name":"grapes"
},
{
"level": "2",
"leafFlag": "1",
"path":"r125/yhes",
"name":"tata"
},
]
var expectedOutput = [
{
"level": "1",
"leafFlag": "1",
"path": "p123",
"name": "food",
"children": [
{
"level": "2",
"leafFlag": "0",
"path": "p123/p345",
"name": "apple"
},
{
"level": "2",
"leafFlag": "1",
"path": "p123/p095",
"name": "banana",
"children": [
{
"level": "3",
"leafFlag": "0",
"path": "p123/p095/p546",
"name": "grapes"
}
]
}
]
},
{
"level": "1",
"leafFlag": "1",
"path": "r125",
"name": "car",
"children": [
{
"level": "2",
"leafFlag": "1",
"path": "r125/yhes",
"name": "tata",
"children": [
{
"level": "3",
"leafFlag": "0",
"path": "r125/yhes/sdie",
"name": "Range Rover"
}
]
},
{
"level": "2",
"leafFlag": "0",
"path": "r125/theys",
"name": "suzuki"
}
]
}
]
i tried the below code but not able to proceed further
private prepareTreeStructure = (inputJson) => {
const treeFormat = (key, index, result) => {
if (key.indexOf('/') === -1) {
result = [...result, ...d[key]];
} else {
result.forEach((item, index) => {
let splitKeyArray = key.split('/');
splitKeyArray.forEach((splitItem, splitIndex) => {
if (splitKeyArray.indexOf(item.path) !== -1) {
if (!item['children']) {
item['children'] = [];
}
if (splitKeyArray.length === splitIndex + 1) {
result[index]['children'] = [...result[index]['children'], ...d[key]];
}
}
});
if (splitKeyArray.indexOf(item.path) !== -1) {
if (!result[index]['children']) {
result[index]['children'] = [];
}
result[index]['children'] = [...result[index]['children'], ...d[key]];
}
});
}
return result;
}
const d = inputJson.reduce((acc, ele) => {
if (!acc[ele.path]) {
acc[ele.path] = [];
}
acc[ele.path].push(ele);
return acc;
}, {});
console.log('dddd ', d);
this.result = [];
Object.keys(d).forEach((key, index) => {
this.result = treeFormat(key, index, this.result);
console.log('out ', this.result);
})
}
prepareTreeStructure(inputJson);
I think you're looking for something like this, works for an n number of levels:
var inputJson = [
{
"level": "1",
"leafFlag": "1",
"path":"p123",
"name":"food"
},
{
"level": "1",
"leafFlag": "1",
"path":"r125",
"name":"car"
},
{
"level": "2",
"leafFlag": "0",
"path":"p123/p345",
"name":"apple"
},
{
"level": "2",
"leafFlag": "1",
"path":"p123/p095",
"name":"banana"
},
{
"level": "3",
"leafFlag": "0",
"path":"p123/p095/p546",
"name":"grapes"
},
{
"level": "2",
"leafFlag": "1",
"path":"r125/yhes",
"name":"tata"
}
]
And the actual code:
var output = [];
inputJson = inputJson.sort((a, b) => (parseInt(a.level) > parseInt(b.level)) ? 1 : -1)
inputJson.forEach(v => {
if (v.level == "1") {
v.children = [];
output.push(v);
}
else {
pathValues = v.path.split("/");
pathValues.pop();
var node = null;
var fullPath = "";
pathValues.forEach(p => {
fullPath = fullPath === "" ? p : fullPath + "/" + p;
node = (node == null ? output : node.children).find(o => o.path === fullPath);
})
node.children = node.children || [];
node.children.push(v);
}
})
console.log(output)
See the jsfiddle: https://jsfiddle.net/L984bo6x/8/
var inputJson = [
{
"level": "1",
"leafFlag": "1",
"path":"p123",
"name":"food"
},
{
"level": "1",
"leafFlag": "1",
"path":"r125",
"name":"car"
},
{
"level": "2",
"leafFlag": "0",
"path":"p123/p345",
"name":"apple"
},
{
"level": "2",
"leafFlag": "1",
"path":"p123/p095",
"name":"banana"
},
{
"level": "3",
"leafFlag": "0",
"path":"p123/p095/p546",
"name":"grapes"
},
{
"level": "2",
"leafFlag": "0",
"path":"r125/yhes",
"name":"tata"
},
]
var expectedOutput = [
{
"level": "1",
"leafFlag": "1",
"path": "p123",
"name": "food",
"children": [
{
"level": "2",
"leafFlag": "0",
"path": "p123/p345",
"name": "apple"
},
{
"level": "2",
"leafFlag": "1",
"path": "p123/p095",
"name": "banana",
"children": [
{
"level": "3",
"leafFlag": "0",
"path": "p123/p095/p546",
"name": "grapes"
}
]
}
]
},
{
"level": "1",
"leafFlag": "1",
"path": "r125",
"name": "car",
"children": [
{
"level": "2",
"leafFlag": "1",
"path": "r125/yhes",
"name": "tata",
"children": [
{
"level": "3",
"leafFlag": "0",
"path": "r125/yhes/sdie",
"name": "Range Rover"
}
]
},
{
"level": "2",
"leafFlag": "0",
"path": "r125/theys",
"name": "suzuki"
}
]
}
]
const groupByLevels = inputJson => {
var levelsObj = {};
inputJson.forEach(ele => {
if (ele.level === "1") {
if (!levelsObj["1"]) {
levelsObj["1"] = [];
}
levelsObj["1"].push(ele)
} else {
if (!levelsObj[ele.level]) {
levelsObj[ele.level] = {};
}
var parKey = ele.path.substr(0, ele.path.lastIndexOf('/'));
if (!levelsObj[ele.level][parKey]) {
levelsObj[ele.level][parKey] = [];
}
levelsObj[ele.level][parKey].push(ele);
}
})
return levelsObj;
}
const mergeByGroups = (currLevelArr, groupJSON) => {
currLevelArr.forEach(ele => {
if (ele.leafFlag == "0") {
return ele;
}
let nextLevel = parseInt(ele.level) + 1 + ""
let nextLevelArr = groupJSON[nextLevel][ele.path];
mergeByGroups(nextLevelArr, groupJSON)
ele.children = nextLevelArr;
})
}
const constructOutput = groupJSON => {
mergeByGroups(groupJSON["1"], groupJSON);
return groupJSON["1"];
}
console.log(JSON.stringify(constructOutput(groupByLevels(inputJson)), null, 4));

Javascript JSON object reorder

I've got the following JSON:
var obj =
{
"workers": [
{
"TimeStamp": "2020-03-13T10:08",
"Status": "status1",
"Name": "one",
"Number": 19.9
},
{
"TimeStamp": "2019-07-19T06:01",
"Status": "status2",
"Name": "one",
"Number": 9
},
{
"TimeStamp": "2020-04-22T05:10",
"Status": "status2",
"Name": "one",
"Number": 10.1
},
{
"TimeStamp": "2019-07-21T23:53",
"Status": "status2",
"Name": "two",
"Number": 16.3
},
{
"TimeStamp": "2019-11-21T05:14",
"Status": "status1",
"Name": "three",
"Number": 122.54
},
...
]
};
As you see there's just 2 different status possible: "status1" and "status2".
Names should be filtered to be shown just once, but combine the two different status.
The respective status should include the "TimeStamp" and "Number" in an array.
In the end it should look like this:
{
"workers": [
{
"Name":"one",
"status1": [
{
"TimeStamp":"2020-03-13T10:08",
"Number": 19.9
}
],
"status2": [
{
"TimeStamp":"2019-07-19T06:01",
"Number": 9
},
{
"TimeStamp": "2020-04-22T05:10",
"Number": 10.1
},
]
},
{
"Name":"two",
"status1": [],
"status2": [
{
"TimeStamp":"2019-07-21T23:53",
"Number": 16.3
}
]
},
{
"Name":"three",
"status1": [
{
"TimeStamp":"2019-11-21T05:14",
"Number": 122.54
}
],
"status2": []
}
]
}
I tried out the following so far:
var writeObj = { 'workers': [] };
for (var i = 0; i < obj.workers.length; i++) {
if(!Object.values(writeObj.workers).includes(obj.workers[i].Name)) {
writeObj['workers'].push({ Name: obj.workers[i].Name, 'status1': [], 'status2': [] });
for (var j = 0; j < obj.workers.length; j++) {
if (obj.workers[j].Name === obj.workers[i].Name && obj.workers[j].Status === 'status1') {
writeObj['workers'][i]['status1'].push({ TimeStamp: obj.workers[j].TimeStamp, Number: obj.workers[j].Number });
} else if (obj.workers[j].Name === obj.workers[i].Name && obj.workers[j].Status === 'status2') {
writeObj['workers'][i]['status2'].push({ TimeStamp: obj.workers[j].TimeStamp, Number: obj.workers[j].Number });
}
}
}
}
I'm stuck and can't see the mistake...
Thanks for any help!
You can aggregate your data using array.reduce:
var obj =
{
"workers": [
{
"TimeStamp": "2020-03-13T10:08",
"Status": "status1",
"Name": "one",
"Number": 19.9
},
{
"TimeStamp": "2019-07-19T06:01",
"Status": "status2",
"Name": "one",
"Number": 9
},
{
"TimeStamp": "2020-04-22T05:10",
"Status": "status2",
"Name": "one",
"Number": 10.1
},
{
"TimeStamp": "2019-07-21T23:53",
"Status": "status2",
"Name": "two",
"Number": 16.3
},
{
"TimeStamp": "2019-11-21T05:14",
"Status": "status1",
"Name": "three",
"Number": 122.54
}
]
};
let output = obj.workers.reduce((acc,cur) => {
let {Name, Status, ...rest} = cur;
let match = acc.find(x => x.Name === Name);
if(!match){
match = { Name: Name };
acc.push(match);
}
if(!match[Status]){
match[Status] = [];
}
match[Status].push(rest);
return acc;
}, []);
console.log({workers: output});
You can use Array#reduce. Group by the Name key according to your format, then take the grouped values as the result. Time complexity is O(n).
var obj = { "workers": [ { "TimeStamp": "2020-03-13T10:08", "Status": "status1", "Name": "one", "Number": 19.9 }, { "TimeStamp": "2019-07-19T06:01", "Status": "status2", "Name": "one", "Number": 9 }, { "TimeStamp": "2020-04-22T05:10", "Status": "status2", "Name": "one", "Number": 10.1 }, { "TimeStamp": "2019-07-21T23:53", "Status": "status2", "Name": "two", "Number": 16.3 }, { "TimeStamp": "2019-11-21T05:14", "Status": "status1", "Name": "three", "Number": 122.54 }, ] };
const grouped = Object.values(obj.workers.reduce((a, e) => {
if (!a[e.Name]) {
a[e.Name] = {Name: e.Name, status1: [], status2: []};
}
a[e.Name][e.Status].push({TimeStamp: e.TimeStamp, Number: e.Number});
return a;
}, {}));
console.log(grouped);

Attributes not showing up in json, restructure json objects

Original json data:
{
"UniversalOne": "",
"CommonOne": "",
"Implementations": [
{
"BirthDate": "",
"UniqueTraits": "",
"Male": {
"Gender": "Male",
"PlaceOfBirth": "",
"Weight": "",
"Height": "",
"EyeColor": ""
},
"Female": {
"Gender": "Female",
"PlaceOfBirth": "",
"Weight": "",
"Height": "",
"EyeColor": ""
},
"Country": [
{
"Orientation": "Male",
"Name": "ABCD",
"County": "East"
},
{
"Orientation": "Male",
"Name": "ABCD",
"County": "West"
},
{
"Orientation": "Female",
"Name": "EFGH",
"County": "East"
},
{
"Orientation": "Female",
"Name": "EFGH",
"County": "West"
},
{
"Orientation": "Female",
"Name": "IJKL"
}
],
"State": [
{
"Address": "XYZ Street",
"ZipCode": "US"
}
],
"Boy": [
{
"AgeGroup": "A",
"Id": 1,
"MaternalName": "",
"PaternalName": ""
},
{
"AgeGroup": "B",
"Id": 2,
"MaternalName": "",
"PaternalName": ""
},
{
"AgeGroup": "C",
"Id": 3,
"MaternalName": "",
"PaternalName": ""
}
]
}
],
"PersonalityTraits": [
{
"Type": "Positive"
},
{
"Type": "Negative"
}
],
"UniversalTwo": "",
"CommonTwo": "",
"EatingHabits": {
"Type": "Excessive"
},
"ReadingHabits": {
"Type": "Fast"
},
"FitnessHabits": {},
"UniversalThree": "",
"CommonThree": ""
}
Expected json response:
{
"UniversalOne": "",
"CommonOne": "",
"Implementations": [
{
"BirthDate": "",
"UniqueTraits": "",
"Male": {
"Gender": "Male",
"PlaceOfBirth": "",
"Weight": "",
"Height": "",
"EyeColor": "",
"Country": [
{
"Orientation": "Male",
"Name": "ABCD"
}
],
"EastCounty": {
"Orientation": "Male",
"Name": "ABCD",
"County": "East"
},
"State": [
{
"Address": "XYZ Street",
"ZipCode": "US"
}
]
},
"Female": {
"Gender": "Female",
"PlaceOfBirth": "",
"Weight": "",
"Height": "",
"EyeColor": "",
"Country": [
{
"Orientation": "Female",
"Name": "EFGH"
},
{
"Orientation": "Female",
"Name": "IJKL"
}
],
"EastCounty": {
"Orientation": "Female",
"Name": "EFGH",
"County": "East"
},
"State": [
{
"Address": "XYZ Street",
"ZipCode": "US"
}
]
},
"Girl": [
{
"AgeGroup": "A",
"identification": [
{
"Number": 1,
"MaternalName": "",
"PaternalName": ""
}
]
},
{
"AgeGroup": "B",
"identification": [
{
"Number": 1,
"MaternalName": "",
"PaternalName": ""
}
]
},
{
"AgeGroup": "C",
"identification": [
{
"Number": 1,
"MaternalName": "",
"PaternalName": ""
}
]
}
]
}
],
"PersonalityTraits": [
{
"Type": "Positive"
},
{
"Type": "Negative"
}
],
"UniversalTwo": "",
"CommonTwo": "",
"EatingHabits": {
"Type": "Excessive"
},
"ReadingHabits": {
"Type": "Fast"
},
"FitnessHabits": {},
"UniversalThree": "",
"CommonThree": ""
}
Questions:
I have three specific questions:
1) How do I retain the attributes that are directly under "Male" and "Female" and also before "Male"? After I run my program these attributes are not shown in my response.
I want to retain attributes like
"BirthDate":"",
"UniqueTraits": "" AND
"Gender": "Male",
"PlaceOfBirth": "",
"Weight": "",
"Height": "",
"EyeColor": ""
exactly as in my original and expected json data.
2) How do I add another EastCounty{} after Country[] both in Male and Female based on "County": East and Orientation? Please refer the original and expected json for reference.
3) How do I restructure Boy[] in original json to the new structure exactly as is shown in Girl[] in expected json response? Note "Id" in Boy[] changes to "Number" in Girl.So if there are multiple "identification" in either of the "AgeGroup" then "Number" would change sequentially for every record.
Current program:
function modifyImplementations(Implementations) {
var finalResult = [];
for (var i = 0; i < Implementations.Implementations.length; i++) {
var currentImplementation = Implementations.Implementations[i];
var targetObj = {
"Male": {
"Gender": "Male",
"Country": [],
"State": currentImplementation.State
},
"Female": {
"Gender": "Female",
"Country": [],
"State": currentImplementation.State
}
};
for (var j = 0; j < currentImplementation.Country.length; j++) {
var currentCountry = currentImplementation.Country[j];
if (currentCountry.Orientation === 'Male') {
targetObj.Male.Country.push(currentCountry);
} else if (currentCountry.Orientation === 'Female') {
targetObj.Female.Country.push(currentCountry);
}
}
finalResult.push(targetObj);
}
return finalResult
}
var x = Object.assign({}, Implementations);
x.Implementations = modifyImplementations(Implementations);
console.log(JSON.stringify(x));
This should be working function which would produce expected result, Please do some refactoring as certainly there are better ways to implement in few areas of code, just quickly done all your needs here to produce expected o/p and also your question needs to be updated with valid JSON's :
function modifyImplementations(Implementations) {
for (let i = 0; i < Implementations.Implementations.length; i++) {
let currentImplementation = Implementations.Implementations[i];
currentImplementation['Male']['Country'] = []
currentImplementation['Female']['Country'] = []
currentImplementation['Male']['EastCounty'] = []
currentImplementation['Female']['EastCounty'] = []
currentImplementation['Male']['State'] = currentImplementation['State'];
currentImplementation['Female']['State'] = currentImplementation['State'];
for (let j = 0; j < currentImplementation.Country.length; j++) {
let currentCountry = currentImplementation.Country[j];
let currentCountryObj = {}
if (currentCountry.Orientation === 'Male') {
if (currentCountry.County && currentCountry.County == "East") {
currentCountryObj['County'] = currentCountry.County
currentCountryObj['Name'] = currentCountry.Name
currentCountryObj['Orientation'] = currentCountry.Orientation
currentImplementation['Male']['EastCounty'].push(currentCountryObj)
} else {
currentCountryObj['Name'] = currentCountry.Name
currentCountryObj['Orientation'] = currentCountry.Orientation
currentImplementation['Male']['Country'].push(currentCountryObj);
}
} else if (currentCountry.Orientation === 'Female') {
if (currentCountry.County && currentCountry.County == "East") {
currentCountryObj['County'] = currentCountry.County
currentCountryObj['Name'] = currentCountry.Name
currentCountryObj['Orientation'] = currentCountry.Orientation
currentImplementation['Female']['EastCounty'].push(currentCountryObj)
} else {
currentCountryObj['Name'] = currentCountry.Name
currentCountryObj['Orientation'] = currentCountry.Orientation
currentImplementation['Female']['Country'].push(currentCountryObj);
}
}
}
delete currentImplementation['Country']
delete currentImplementation['State']
let mapObj = [];
for (items of currentImplementation.Boy) {
let objs = currentImplementation.Boy.filter((obj) => {
return items.AgeGroup === obj.AgeGroup
})
mapObj.push(objs)
currentImplementation.Boy = currentImplementation.Boy.filter(e => e.AgeGroup !== items.AgeGroup);
}
let finalArray = mapObj.filter(e => e.length > 0)
currentImplementation['Girl'] = []
for (anArray of finalArray) {
let finalObj = {}
finalObj.identification = [];
if (anArray.length && anArray.length > 1) {
let number = 1
for (oneObj of anArray) {
let objs = {};
objs['Number'] = number
objs['MaternalName'] = oneObj['MaternalName']
objs['PaternalName'] = oneObj['PaternalName']
number += 1
finalObj['AgeGroup'] = oneObj.AgeGroup
finalObj.identification.push(objs);
}
} else if (anArray.length == 1) {
let objs = {};
finalObj['AgeGroup'] = anArray[0].AgeGroup
objs = {};
objs['Number'] = 1
objs['MaternalName'] = anArray[0]['MaternalName']
objs['PaternalName'] = anArray[0]['PaternalName']
finalObj.identification.push(objs);
}
currentImplementation['Girl'].push(finalObj)
delete currentImplementation['Boy']
}
}
return Implementations
}

Filtering nested key value pair based on a specific value

I am doing key value pair mapping for the first time and not been able to approach. I have a key value pair like :
trips= {
date1: [
{
"id": 1,
"Place": "Delhi",
"Number": "001",
"Vehicle": {"id":"veh1", "number": "AN01001"}
},
{
"id": 2,
"Place": "Bangalore",
"Number": "002",
"Vehicle": {"id":"veh2", "number": "AN01002"}
},
{
"id": 3,
"Place": "Pune",
"Number": "003",
"Vehicle": {"id":"veh3", "number": "AN01003"}
}
],
date2: [
{
"id": 1,
"Place": "Lucknow",
"Number": "001",
"Vehicle": {"id":"veh1", "number": "AN01002"}
},
{
"id": 3,
"Place": "Pune",
"Number": "003",
"Vehicle": {"id":"veh3", "number": "AN01003"}
}
],
date3: [
{
"id": 1,
"Place": "Delhi",
"Number": "001",
"Vehicle": {"id":"veh1", "number": "AN01001"}
},
{
"id": 2,
"Place": "Bangalore",
"Number": "002",
"Vehicle": {"id":"veh2", "number": "AN01002"}
}
]
}
for (date in trips) {
var places = trips[date]
for (var i = 0; i < places.length; ++i) {
var place = places[i]
console.log('place', place)
console.log('Vehicle', place.Vehicle)
}
}
Inside dates the data are stored in form of array which have key value pair. I need to print all the dates which have vehicle id as "veh2" inside it. I am trying to loop through the data. but not finding the right way after a certain point where the array starts.
I have been able to loop through one nested key value pair
for (key in trips){
var value= trips[key]
for (k in value)
{
//further nested logic
}
}
Here's one way to get all the dates that contain your Vehicle with id === veh2:
const t = Object.entries(trips);
const res = t.filter((dates) => {
return dates[1].some((d, e) => {
return d.Vehicle.id == 'veh2';
});
});
console.log(res);
This would return arrays for date1 and date3 (which contain veh2)
EDIT (version2):
This returns the dates much cleaner:
let res = [];
for(let i in trips) {
const found = trips[i].filter((dates) => dates.Vehicle.id == 'veh2');
found.length && res.push(trips[i]);
}
console.log(res);
I think your major problem is the wrong structured data as #Nina Scholz already mentioned, when having this corrected it is pretty easy to run through everything:
trips= {
date1: [
{
"id": 1,
"Place": "Delhi",
"Number": "001",
"Vehicle": {"id":"veh1", "number": "AN01001"}
},
{
"id": 2,
"Place": "Bangalore",
"Number": "002",
"Vehicle": {"id":"veh2", "number": "AN01002"}
},
{
"id": 3,
"Place": "Pune",
"Number": "003",
"Vehicle": {"id":"veh3", "number": "AN01003"}
}
],
date2: [
{
"id": 1,
"Place": "Lucknow",
"Number": "001",
"Vehicle": {"id":"veh1", "number": "AN01002"}
},
{
"id": 3,
"Place": "Pune",
"Number": "003",
"Vehicle": {"id":"veh3", "number": "AN01003"}
}
],
date3: [
{
"id": 1,
"Place": "Delhi",
"Number": "001",
"Vehicle": {"id":"veh1", "number": "AN01001"}
},
{
"id": 2,
"Place": "Bangalore",
"Number": "002",
"Vehicle": {"id":"veh2", "number": "AN01002"}
}
]
}
for (date in trips) {
var places = trips[date]
for (var i = 0; i < places.length; ++i) {
var place = places[i]
console.log('place', place)
console.log('Vehicle', place.Vehicle)
}
}
With poper formatted objects and arrays, you could filter single places where the id matches.
var trips = { date1: [{ id: 1, Place: "Delhi", Number: "001", Vehicle: { id: "veh1", number: "AN01001" } }, { id: 2, Place: "Bangalore", Number: "002", Vehicle: { id: "veh2", number: "AN01002" } }, { id: 3, Place: "Pune", Number: "003", Vehicle: { id: "veh3", number: "AN01003" } }], date2: [{ id: 1, Place: "Lucknow", Number: "001", Vehicle: { id: "veh1", number: "AN01002" } }, { id: 3, Place: "Pune", Number: "003", Vehicle: { id: "veh3", number: "AN01003" } }], date3: [{ id: 1, Place: "Delhi", Number: "001", Vehicle: { id: "veh1", number: "AN01001" } }, { id: 2, Place: "Bangalore", Number: "002", Vehicle: { id: "veh2", number: "AN01002" } }] },
id = "veh2",
result = Object.keys(trips).reduce(function (r, k) {
return r.concat(trips[k].filter(function (place) {
return place.Vehicle.id === id;
}));
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do it with the following code.
trips = {
date1: [{
"id": 1,
"Place": "Delhi",
"Number": "001",
"Vehicle": {
"id": "veh1",
"number": "AN01001"
}
},
{
"id": 2,
"Place": "Bangalore",
"Number": "002",
"Vehicle": {
"id": "veh2",
"number": "AN01002"
}
},
{
"id": 3,
"Place": "Pune",
"Number": "003",
"Vehicle": {
"id": "veh3",
"number": "AN01003"
}
}
],
date2: [{
"id": 1,
"Place": "Lucknow",
"Number": "001",
"Vehicle": {
"id": "veh1",
"number": "AN01002"
}
},
{
"id": 3,
"Place": "Pune",
"Number": "003",
"Vehicle": {
"id": "veh3",
"number": "AN01003"
}
}
],
date3: [{
"id": 1,
"Place": "Delhi",
"Number": "001",
"Vehicle": {
"id": "veh1",
"number": "AN01001"
}
},
{
"id": 2,
"Place": "Bangalore",
"Number": "002",
"Vehicle": {
"id": "veh2",
"number": "AN01002"
}
}
]
};
var results = [];
for (var date in trips) {
for (var index = 0; index < trips[date].length; index++) {
var data = trips[date][index];
var vehicle = data.Vehicle;
if (vehicle.number == 'AN01002') {
results.push(data);
}
}
}
console.log(results);
you can use foreach like this :
trips.foreach((item) =>{
//here item is date1, date2
// then you can do
item.id = 2; // every stuff you want !!!
});

Recursive iteration over dynamically nested object array

I am using angular JS and one of their examples:http://jsfiddle.net/furf/EJGHX/
I need to take the data when the update function occurs and add some values to it before I send to the server. (If doing this with angular instead of js would be better let me know)
I'm trying to get the 'parentid' and the 'index' and update the children.
Here is the data I'm looping through
{
"children": [{
"id": "5",
"parentid": "0",
"text": "Device Guides",
"index": "1",
"children": [{
"id": "10",
"index": "0",
"text": "Grandstream GXP-21XX"
}, {
"id": "11",
"index": "1",
"text": "Polycom Soundstation/Soundpoint"
}, {
"id": "23",
"index": "2",
"text": "New Polycom"
}]
}, {
"id": "6",
"parentid": "0",
"text": "Pre-Sales Evaluation",
"index": "0",
"children": []
}, {
"id": "7",
"parentid": "0",
"text": "Router Setup Guides",
"index": "2",
"children": [{
"id": "9",
"index": "0",
"text": "Sonicwall"
}, {
"id": "12",
"index": "1",
"text": "Cisco"
}]
}, {
"id": "9",
"parentid": "7",
"text": "Sonicwall",
"index": "0",
"children": []
}, {
"id": "10",
"parentid": "5",
"text": "Grandstream GXP-21XX",
"index": "0",
"children": []
}, {
"id": "11",
"parentid": "5",
"text": "Polycom Soundstation/Soundpoint",
"index": "1",
"children": []
}, {
"id": "12",
"parentid": "7",
"text": "Cisco",
"index": "1",
"children": []
}, {
"id": "15",
"parentid": "0",
"text": "Post-Sales Implementation Check List",
"index": "7",
"children": [{
"id": "16",
"index": "0",
"text": "Porting and New Number Details"
}, {
"id": "18",
"index": "1",
"text": "Partner Setup"
}, {
"id": "19",
"index": "2",
"text": "test"
}, {
"id": "21",
"index": "3",
"text": "test"
}]
}, {
"id": "16",
"parentid": "15",
"text": "Porting and New Number Details",
"index": "0",
"children": []
}, {
"id": "18",
"parentid": "15",
"text": "Partner Setup",
"index": "1",
"children": []
}, {
"id": "19",
"parentid": "15",
"text": "test",
"index": "2",
"children": []
}, {
"id": "20",
"parentid": "0",
"text": "test",
"index": "11",
"children": []
}, {
"id": "21",
"parentid": "15",
"text": "test",
"index": "3",
"children": []
}, {
"id": "23",
"parentid": "5",
"text": "New Polycom",
"index": "2",
"children": []
}, {
"id": "24",
"parentid": "0",
"text": "Test Markup",
"index": "14",
"children": []
}, {
"id": "25",
"parentid": "0",
"text": "test",
"index": "15",
"children": []
}]
}
This is how I'm currently looping through it, but it only gets the first dimension
for (i = 0, l = data.length; i < l; i++) {
parentid = data[i].id == null ? '0' : data[i].id;
data[i].index = i;
if (data[i].children) {
if (data[i].children.length > 0) {
for (q = 0, r = data[i].children.length; q < r; q++) {
data[i].children[q].parentid = parentid;
data[i].children[q].index = q;
}
}
}
}
I found this one on another fiddle, but I don't know how I would grab the parentid or the index
$.each(target.children, function(key, val) { recursiveFunction(key, val) });
function recursiveFunction(key, val) {
actualFunction(key, val);
var value = val['children'];
if (value instanceof Object) {
$.each(value, function(key, val) {
recursiveFunction(key, val)
});
}
}
function actualFunction(key, val) {}
If I'm understanding you correctly, you want each 'child' to have a parentID (defined by its parent; 0 otherwise) and an index (based on its position within it sibling set).
function normalize(parent) {
if (parent && parent.children) {
for (var i = 0, l = parent.children.length; i < l; ++i) {
var child = parent.children[i];
child.index = i;
if (!child.parentId) child.parentId = parent.id || '0';
normalize(child);
}
}
}
normalize(data);
Recursion is calling function inside the same function. Your sample is not a recursion at all;
function runRecursive(input) {
for (var i = 0, l = input.length; i < l; i++) {
var current = input[i];
parentid = current.id == null ? '0' : current.id;
current.index = i;
if (current.children && current.children.length > 0) {
runRecursive(current.children);
};
};
};
runRecursive(data.children);
Also you should define i and l with var keyword, otherwise it will be located in window context and recursion logic will broken.
Though I don't get what is parentid variable for and why it defined outside visible code.

Categories