Sort nested JSON array of objects - javascript

I have an array of objects as below. I want to recursively sort this based on the key values
{
"settingsList": [
{
"category1": [
{
"categoryName": "DRIVER",
"description": "DRIVER",
"sequence": 1
},
{
"categoryName": "BALL",
"description": "BALL",
"sequence": 2
},
{
"categoryName": "SAMPLE",
"description": "SAMPLE",
"sequence": 3
},
{
"categoryName": "USER",
"description": "USER",
"sequence": 4
}
]
},
{
"category2": [
{
"paramName": "CPP",
"description": "CPP",
"sequence": 1
},
{
"paramName": "PP",
"description": "PP",
"sequence": 2
},
{
"paramName": "MP",
"description": "MP",
"sequence": 3
}
]
}
{
"source": {
"instanceName": "instance_1"
}
}
]
}
How can I efficiently sort recursively to display it sorted alphabetically on the key values.
Expected output:
{
"settingsList": [
{
"category": [
{
"categoryName": "BALL",
"description": "BALL",
"sequence": 2
},
{
"categoryName": "DRIVER",
"description": "DRIVER",
"sequence": 1
},
{
"categoryName": "SAMPLE",
"description": "SAMPLE",
"sequence": 3
},
{
"categoryName": "USER",
"description": "USER",
"sequence": 4
}
]
},
{
"category2": [
{
"paramName": "CPP",
"description": "CPP",
"sequence": 1
},
{
"paramName": "MP",
"description": "MP",
"sequence": 3
},
{
"paramName": "PP",
"description": "PP",
"sequence": 2
}
]
},
{
"source": {
"instanceName": "instance_1"
}
}
]
}
below is the sample code that was tried
var object = {
"settingsList": [
{
"category1": [
{
"categoryName": "DRIVER",
"description": "DRIVER",
"sequence": 1
},
{
"categoryName": "BALL",
"description": "BALL",
"sequence": 2
},
{
"categoryName": "SAMPLE",
"description": "SAMPLE",
"sequence": 3
},
{
"categoryName": "USER",
"description": "USER",
"sequence": 4
}
]
},
{
"category2": [
{
"paramName": "CPP",
"description": "CPP",
"sequence": 1
},
{
"paramName": "PP",
"description": "PP",
"sequence": 2
},
{
"paramName": "MP",
"description": "MP",
"sequence": 3
}
]
},
{
"source": {
"instanceName": "instance_1"
}
}
]
}
var keys = Object.keys(object);
var sortedKeys = keys.sort((key1, key2)=>{
key1 = key1.toLowerCase();
key2 = key2.toLowerCase();
if(key1 < key2) return -1;
if(key1 > key2) return 1;
return 0;
})
function sortData(object){
var newObject = {},
keys = Object.keys(object);
keys.sort(function(key1, key2){
key1 = key1.toLowerCase();
key2 = key2.toLowerCase();
if(key1 < key2) return -1;
if(key1 > key2) return 1;
return 0;
});
for(var index in keys){
var key = keys[index];
if(typeof object[key] == 'object' && !(object[key] instanceof Array)){
newObject[key] = sortData(object[key]);
} else {
newObject[key] = object[key];
}
}
return newObject;
}
var sortedData=sortData(object)
console.log(sortedData)
....................................................................................................................................................................................................................................................................

What you tried to achieved is called deep sort.
You can use deep-sort-object library as follow :
var sortobject = require('deep-sort-object');
var sortedData = sortobject(object);
console.log(sortedData);
Or if you don't want to use a library, you can use this gist as reference.

Here is an iterative solution using object-scan
// const objectScan = require('object-scan');
const myData = { settingsList: [{ category1: [{ categoryName: 'DRIVER', description: 'DRIVER', sequence: 1 }, { categoryName: 'BALL', description: 'BALL', sequence: 2 }, { categoryName: 'SAMPLE', description: 'SAMPLE', sequence: 3 }, { categoryName: 'USER', description: 'USER', sequence: 4 }] }, { category2: [{ paramName: 'CPP', description: 'CPP', sequence: 1 }, { paramName: 'PP', description: 'PP', sequence: 2 }, { paramName: 'MP', description: 'MP', sequence: 3 }] }, { source: { instanceName: 'instance_1' } }] };
const sort = (data) => {
const logic = {
'settingsList[*].category1': (value) => value.sort((a, b) => a.categoryName.localeCompare(b.categoryName)),
'settingsList[*].category2': (value) => value.sort((a, b) => a.paramName.localeCompare(b.paramName))
};
objectScan(Object.keys(logic), {
filterFn: ({ value, matchedBy }) => {
matchedBy.forEach((needle) => logic[needle](value));
}
})(data);
};
console.log(sort(myData));
// => undefined
console.log(myData);
// => { settingsList: [ { category1: [ { categoryName: 'BALL', description: 'BALL', sequence: 2 }, { categoryName: 'DRIVER', description: 'DRIVER', sequence: 1 }, { categoryName: 'SAMPLE', description: 'SAMPLE', sequence: 3 }, { categoryName: 'USER', description: 'USER', sequence: 4 } ] }, { category2: [ { paramName: 'CPP', description: 'CPP', sequence: 1 }, { paramName: 'MP', description: 'MP', sequence: 3 }, { paramName: 'PP', description: 'PP', sequence: 2 } ] }, { source: { instanceName: 'instance_1' } } ] }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan#14.4.0"></script>
Disclaimer: I'm the author of object-scan

Related

if name of array object same then combine array object in ts

I have an array of objects coming from backend.
var values = [
{
"name": "Patient Introductions",
"series": [
{
"name": "Organization ABC",
"value": 3
}
]
},
{
"name": "Patient Assessment",
"series": [
{
"name": "Organization ABC",
"value": 2.5
}
]
},
{
"name": "Patient Introductions",
"series": [
{
"name": "Organization XYZ",
"value": 2.5
}
]
},
{
"name": "Patient Assessment",
"series": [
{
"name": "Organization XYZ",
"value": 3.3
}
]
},
];
I want to combine the inner array's objects and get one single array of objects for same name of objects.
var output = [
{
"name": "Patient Introductions",
"series": [
{
"name": "Organization ABC",
"value": 3
},
{
"name": "Organization XYZ",
"value": 2.5
}
]
},
{
"name": "Patient Assessment",
"series": [
{
"name": "Organization ABC",
"value": 2.5
},
{
"name": "Organization XYZ",
"value": 3.3
}
]
},
];
I think, I need to use reduce but not sure how I can combine objects of series of same name.
Please help and guide. Thanks
You are right with reducer
var values = [
{
"name": "Patient Introductions",
"series": [
{
"name": "Organization ABC",
"value": 3
}
]
},
{
"name": "Patient Assessment",
"series": [
{
"name": "Organization ABC",
"value": 2.5
}
]
},
{
"name": "Patient Introductions",
"series": [
{
"name": "Organization XYZ",
"value": 2.5
}
]
},
{
"name": "Patient Assessment",
"series": [
{
"name": "Organization XYZ",
"value": 3.3
}
]
},
];
var result = values.reduce((acc, curr) => {
var existing = acc.find(element => element.name === curr.name);
if(existing) {
existing.series.push(...curr.series);
} else {
acc.push(curr);
}
return acc;
}, []);
console.log(result);
Make a new empty array
loop through your original array if the name does not exist in the
new array then add to it'
if the name existed just add the new array to it
this way ensures no duplicate name will be in the array
var values = [
{
name: "Patient Introductions",
series: [
{
name: "Organization ABC",
value: 3,
},
],
},
{
name: "Patient Assessment",
series: [
{
name: "Organization ABC",
value: 2.5,
},
],
},
{
name: "Patient Introductions",
series: [
{
name: "Organization XYZ",
value: 2.5,
},
],
},
{
name: "Patient Assessment",
series: [
{
name: "Organization XYZ",
value: 3.3,
},
],
},
];
let newValues = [];
values.forEach((value) => {
let index = newValues.findIndex((item) => item.name === value.name);
if (index === -1) {
newValues.push({ name: value.name, series: [value.series[0]] });
} else {
newValues[index].series.push(value.series[0]);
}
});
console.log(newValues)

Loop through JSON in dataLayer

I would like to get the summed value of all the arrays in the "products" object (price * quantity). The summed value should be returned in the return.
Do you have any ideas how to do that?
{
"event": "checkout",
"ecommerce": {
"checkout": {
"actionField": {
"step": 2,
"option": "Initiate checkout",
"action": "checkout"
},
"products": [
{
"id": "52",
"name": "Turystyczna kuchenka gazowa SMILE-KN-03/1K",
"price": 161.788618,
"brand": "",
"category": "kuchenki-elektryczne-i-gazowe",
"variant": "",
"quantity": "1"
},
{
"id": "36",
"name": "Kuchnia gazowa MPM-51-KGF-21",
"price": 641.463415,
"brand": "",
"category": "kuchnie-gazowe",
"variant": "",
"quantity": "1"
}
]
}
},
"gtm.uniqueEventId": 12
}
const g = {
event: 'checkout',
ecommerce: {
checkout: {
actionField: {
step: 2,
option: 'Initiate checkout',
action: 'checkout',
},
products: [
{
id: '52',
name: 'Turystyczna kuchenka gazowa SMILE-KN-03/1K',
price: 161.788618,
brand: '',
category: 'kuchenki-elektryczne-i-gazowe',
variant: '',
quantity: '1',
},
{
id: '36',
name: 'Kuchnia gazowa MPM-51-KGF-21',
price: 641.463415,
brand: '',
category: 'kuchnie-gazowe',
variant: '',
quantity: '1',
},
],
},
},
'gtm.uniqueEventId': 12,
};
const c = g.ecommerce.checkout.products.reduce((acc, curr) => {
acc += curr.price * curr.quantity;
return acc;
}, 0);
console.log(c)
guess you want something like this?

React/ES6 reduce object

I have the following object that holds workouts for specific days:
{
"2019-03-02": [
{
"id": 1,
"workout_day": "2019-03-02",
"title": "Swimming",
"description": "",
"completed": true,
"points": 5
},
{
"id": 2,
"workout_day": "2019-03-02",
"title": "Running",
"description": "",
"completed": false,
"points": 0
},
{
"id": 3,
"workout_day": "2019-03-02",
"title": "Rowing",
"description": "",
"completed": true,
"points": 3
},
],
"2019-03-05": [...]
}
I want to get a new object that shows for each day how many workouts exist, how much of them have been completed and a sum for the points, like so:
{
"2019-03-02": {
"workouts": 3,
"workouts_completed": 2,
"total_points": 8
},
"2019-03-05: {...}
}
However, I'm totally stuck at the moment. Thanks for help!
You've multiple solution to achieve this. Here is one that combined Object.entries + Array.reduce.
Object.entries(input).reduce((acc, [date, workouts]) => {
const completed = workouts.filter(workout => workout.completed);
return {
...acc,
[date]: {
workouts: workouts.length,
workouts_completed: completed.length,
total_points: completed.reduce((acc, workout) => acc + workout.points, 0),
}
};
}, {});
Note that Object.entries is not available in all the major browsers.
This will reduce your data into the one you want to transform to
const data = {
'2019-03-02': [{
id: 1,
workout_day: '2019-03-02',
title: 'Swimming',
description: '',
completed: true,
points: 5
},
{
id: 2,
workout_day: '2019-03-02',
title: 'Running',
description: '',
completed: false,
points: 0
},
{
id: 3,
workout_day: '2019-03-02',
title: 'Rowing',
description: '',
completed: true,
points: 3
}
],
'2019-03-03': [{
id: 1,
workout_day: '2019-03-02',
title: 'Swimming',
description: '',
completed: true,
points: 7
},
{
id: 2,
workout_day: '2019-03-02',
title: 'Running',
description: '',
completed: false,
points: 0
},
{
id: 3,
workout_day: '2019-03-02',
title: 'Rowing',
description: '',
completed: false,
points: 3
}
]
}
const reducedData = Object.keys(data).reduce((acc, key) => {
acc[key] = {
workouts: data[key].length,
workouts_completed: data[key].reduce((acc, item) => {
if (item.completed) return acc + 1
return acc
}, 0),
total_points: data[key].reduce((acc, item) => {
return acc + item.points
}, 0)
}
return acc
}, {})
console.log(reducedData)
Assuming you have your object that holds workouts for specific days in an object called json, you can use Object.keys() to iterate over all the keys. Then you can map over this and get the workouts for one specific day at a time. You can then use that to create an object for each day. To calculate stuff like totalPoints you'll use reduce to sum up the total points.
Object.keys(json).map(key => {
return {
[key]: {
workoutsCompleted: json[key].length,
totalPoints: json[key].reduce((accum, workout) => accum + workout.points, 0)
}
};
});
This does the job.
I used Array.prototype.reduce and destructuring with default values.
var data = {
"2019-03-02": [{
"id": 1,
"workout_day": "2019-03-02",
"title": "Swimming",
"description": "",
"completed": true,
"points": 5
}, {
"id": 2,
"workout_day": "2019-03-02",
"title": "Running",
"description": "",
"completed": false,
"points": 0
}, {
"id": 3,
"workout_day": "2019-03-02",
"title": "Rowing",
"description": "",
"completed": true,
"points": 3
},
],
"2019-03-05": [{
"id": 1,
"workout_day": "2019-03-02",
"title": "Swimming",
"description": "",
"completed": false,
"points": 0
}, {
"id": 2,
"workout_day": "2019-03-02",
"title": "Running",
"description": "",
"completed": false,
"points": 0
}, {
"id": 3,
"workout_day": "2019-03-02",
"title": "Rowing",
"description": "",
"completed": true,
"points": 8
},
]
};
var result = {};
for (let key in data) {
result[key] = data[key].reduce(({
workouts = 0,
workouts_completed = 0,
total_points = 0
}, currentValue) => {
return {
workouts: workouts + 1,
workouts_completed: currentValue.completed ? workouts_completed + 1 : workouts_completed,
total_points: total_points + currentValue.points
};
}, {});
}
console.log(result);
const result = {};
for(const [workout_day, entries] of Object.entries(input)) {
result[workout_day] = {
workouts: entries.length,
workouts_completed: entries.reduce((acc, e) => acc + e.completed, 0),
total_points: entries.reduce((acc, e) => acc + e.points, 0),
};
}
Object.entries is quite useful for mapping objects.
const data = {
"2019-03-02": [
{
"id": 1,
"workout_day": "2019-03-02",
"title": "Swimming",
"description": "",
"completed": true,
"points": 5
},
{
"id": 2,
"workout_day": "2019-03-02",
"title": "Running",
"description": "",
"completed": false,
"points": 0
},
{
"id": 3,
"workout_day": "2019-03-02",
"title": "Rowing",
"description": "",
"completed": true,
"points": 3
},
],
"2019-03-05": []
};
function makeReport (report, workout) {
return {
workouts: report.workouts + 1,
workouts_completed: workout.completed ? report.workouts_completed + 1 : report.workouts_completed,
total_points: report.total_points + workout.points
};
}
const out = Object.entries(data).reduce(function (report, [date, workouts]) {
return {
...report,
[date]: workouts.reduce(makeReport, { workouts: 0, workouts_completed: 0, total_points: 0 })
};
}, {});
console.log(out);
which logs:
{ '2019-03-02': { workouts: 3, workouts_completed: 2, total_points: 8 },
'2019-03-05': { workouts: 0, workouts_completed: 0, total_points: 0 } }

How to make recursively nested array in javascript?

Below is the json I have:
{
"name": "test",
"characteristics": [
{
"name": "A",
"description": "",
"comprisedOf": [
{
"name": "A1",
"description": "",
"comprisedOf": [
{
"name": "A1.1",
"description": "",
"value": "10"
},
{
"name": "A1.2",
"description": "",
"value": "5"
}
]
},
{
"name": "A2",
"description": "",
"value": "100"
},
{
"name": "A3",
"description": "",
"value": "20"
},
{
"name": "A4",
"description": "",
"value": "50"
}
]
},
{
"name": "B",
"description": "",
"value": "10"
}
]
}
Here I have 2 characteristics object of "test" - A and B.These 2 objects may or may not have "comprisedOf" array. For Eg A has"comprisedOf" array whereas B has not. These comprisedOf array further may or may not have comprisedof objects array.
Now i have to make an array out of this which should be like the given below array:-
[
{
"name": "test",
"children": [
{
"name": "A",
"children": [
{
"name":"A1",
"children:: [
{
"name": "A1.1"
},
{
"name": "A1.2"
}
]
},
{
"name": "A2"
},
{
"name": "A3"
},
{
"name": "A4"
}
]
},
{
"name": "B"
}
]
}
]
How this array can be formed recursively out of the first array?
Thanks so much!!
EDIT:- Here's what I have tried:-
var makeChildrenAll = function(dataChar){
dataChar.forEach(function(char){
if(char.comprisedOf) {
makeChildrenAll(char.comprisedOf);
}
childrenData.push({
name: char.name,
description: char.description,
children: childrenData
});
});
};
makeChildrenAll(dataChar);
In order to be recursive you want the function to return and be able to assign that return to current object
Something like
function mapItems(arr){
// return new array
return arr.reduce((a,c)=>{
var newObj={name:c.name};
if(Array.isArray(c.comprisedOf)){
// use returned array of recursive function to assign to `children` property
newObj.children = mapItems(c.comprisedOf)
}
return a.concat(newObj)
},[])
}
console.log(mapItems(data.characteristics))
.as-console-wrapper { max-height: 100%!important;}
<script>
var data ={
"name": "test",
"characteristics": [
{
"name": "A",
"description": "",
"comprisedOf": [
{
"name": "A1",
"description": "",
"comprisedOf": [
{
"name": "A1.1",
"description": "",
"value": "10"
},
{
"name": "A1.2",
"description": "",
"value": "5"
}
]
},
{
"name": "A2",
"description": "",
"value": "100"
},
{
"name": "A3",
"description": "",
"value": "20"
},
{
"name": "A4",
"description": "",
"value": "50"
}
]
},
{
"name": "B",
"description": "",
"value": "10"
}
]
}
</script>
You could take a different start array and use a destructuring for the wanted properties.
function mapItems(array) {
return array.map(({ name, comprisedOf }) =>
Object.assign({ name }, comprisedOf && { children: mapItems(comprisedOf) }));
}
var data = { name: "test", characteristics: [{ name: "A", description: "", comprisedOf: [{ name: "A1", description: "", comprisedOf: [{ name: "A1.1", description: "", value: "10" }, { name: "A1.2", description: "", value: "5" }] }, { name: "A2", description: "", value: "100" }, { name: "A3", description: "", value: "20" }, { name: "A4", description: "", value: "50" }] }, { name: "B", description: "", value: "10" }] };
console.log(mapItems([{ name: data.name, comprisedOf: data.characteristics }]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES5
function mapItems(array) {
return array.map(function (o) {
var r = { name: o.name };
if (o.comprisedOf) {
r.children = mapItems(o.comprisedOf);
}
return r;
});
}
var data = { name: "test", characteristics: [{ name: "A", description: "", comprisedOf: [{ name: "A1", description: "", comprisedOf: [{ name: "A1.1", description: "", value: "10" }, { name: "A1.2", description: "", value: "5" }] }, { name: "A2", description: "", value: "100" }, { name: "A3", description: "", value: "20" }, { name: "A4", description: "", value: "50" }] }, { name: "B", description: "", value: "10" }] };
console.log(mapItems([{ name: data.name, comprisedOf: data.characteristics }]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

traversing through JSON string to inner levels using recursive function

I have a JSON input which can go to any number of levels.
I'm giving an input sample of
var d=getEntities( {"Categories":
{
"Facets":
[
{
"count": 1,
"entity": "Company",
"Company":
[
{
"entity": "Ford Motor Co",
"Ford_Motor_Co":
[
{
"count": 1,
"entity": "Ford"
}
]
}
]
},
{
"count": 4,
"entity": "Country",
"Country": [
{
"entity": "Germany",
"Germany": [
{
"count": 1,
"entity": "Germany"
}
],
"currency": "Euro (EUR)"
},
{
"entity": "Italy",
"Italy": [
{
"count": 1,
"entity": "Italy"
}
],
"currency": "Euro (EUR)"
},
{
"entity": "Japan",
"Japan": [
{
"count": 1,
"entity": "Japan"
}
],
"currency": "Yen (JPY)"
},
{
"entity": "South Korea",
"South_Korea": [
{
"count": 1,
"entity": "South Korea"
}
],
"currency": "Won (KRW)"
}
]
},
{"count": 5,
"entity": "Persons",
"Persons": [
{
"count": 2,
"entity": "Dodge"
},
{
"count": 1,
"entity": "Dodge Avenger"
},
{
"count": 1,
"entity": "Major League"
},
{
"count": 1,
"entity": "Sterling Heights"
}
]
}
]
}});
I want to add the key value "Entity" in all levels to an array using recursion,
I'm able to collect the data from first level using the string
<html>
<head>
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript" src="dataDumper.js"></script>
<script type="text/javascript">
var testJSON = {"Categories":
{
"Facets":
[
{
"count": 1,
"entity": "Company",
"Company":
[
{
"entity": "Ford Motor Co",
"Ford_Motor_Co":
[
{
"count": 1,
"entity": "Ford"
}
]
}
]
},
{
"count": 4,
"entity": "Country",
"Country": [
{
"entity": "Germany",
"Germany": [
{
"count": 1,
"entity": "Germany"
}
],
"currency": "Euro (EUR)"
},
{
"entity": "Italy",
"Italy": [
{
"count": 1,
"entity": "Italy"
}
],
"currency": "Euro (EUR)"
},
{
"entity": "Japan",
"Japan": [
{
"count": 1,
"entity": "Japan"
}
],
"currency": "Yen (JPY)"
},
{
"entity": "South Korea",
"South_Korea": [
{
"count": 1,
"entity": "South Korea"
}
],
"currency": "Won (KRW)"
}
]
},
{"count": 5,
"entity": "Persons",
"Persons": [
{
"count": 2,
"entity": "Dodge"
},
{
"count": 1,
"entity": "Dodge Avenger"
},
{
"count": 1,
"entity": "Major League"
},
{
"count": 1,
"entity": "Sterling Heights"
}
]
}
]
}};
function scan(obj)
{
var k;
if (obj.hasOwnProperty('entity')) {
for (k in obj){
if (obj.hasOwnProperty(k)){
scan( obj[k] );
}
}
}
else{
if(k=='entity')
{
alert(obj.entity);
}
}
};
scan(testJSON);
</script>
</head>
<body>
</body>
</html>
How do I get in to the inner levels for JSON string using recursive functions?
I have made a jsfiddle which traverses every object,array and value in the JS object like so...
function scan(obj) {
var k;
if (obj instanceof Object) {
for (k in obj){
if (obj.hasOwnProperty(k)){
//recursive call to scan property
scan( obj[k] );
}
}
} else {
//obj is not an instance of Object so obj here is a value
};
};
I get no recursion error (in Chrome). Can you use this to do what you want?
If you need to test if an object is an array use if (obj instanceof Array)
To test if an object has an "entity" property use if (obj.hasOwnProperty('entity'))
To add (or modify an existing) "entity" property use obj.entity = value or obj['entity'] = value
(function recur( obj ) {
Object.keys( obj ).forEach( function( prop ) {
// Check if the property is an object
if ( ({}).toString.apply( prop ) === '[object Object]' ) {
// If it is, recall this function
recur( prop );
}
} );
} () );
I haven't added your logic, but you get the idea of how to recursively traverse your object.
Say I have a structure like the following:
var aObject = {
items: [],
children: {}
}
Children is an associative array that contains more aObjects. So it could look like this:
var aObject = {
items: [],
children: {
"subgroup1": {
items: [],
children: {}
},
"subgroup2": {
items: [],
children: {}
}
}
}
I have an item that contains an array of subgroups:
["subgroup1", "subgroup1a"]
Each subgroup is a 'location'. The item needs to be placed at:
aObject.children[array[0]].children[array[1]].items
At each level, we have to check if children[array[i]] exists, and if not, create it. You can't simply write aObject.children[array[0]].children[array[1]].items.push(item) because children[array[0]] might not already exist and we will get an error.
This can be solved using recursion! (AngularJS)
function recursive(aLevel, aItem, aArray, aIndex){
var lLevel = aLevel;
// If we have reached the end of the array
if (aIndex === aArray.length){
// Insert
aLevel.items.push(aItem);
} else {
// If the subgroup doesn't exist, create it
if (typeof aLevel.children[aArray[aIndex]] === 'undefined'){
aLevel.children[aArray[aIndex]] = {
items: [],
children: {}
};
}
// Move into
recursive(aLevel.children[aArray[aIndex]], aItem, aArray, aIndex+1);
}
}
aObject = {
items: [],
children: {},
}
angular.forEach(items, function(item, i){
var location = item.location;
if (location.length == 0){
aObject.items.push(item);
} else {
recursive(aObject, item, location, 0);
}
});
The final aObject would look like this:
var aObject = {
items: [],
children: {
"subgroup1": {
items: [],
children: {
"subgroup1a": {
items: [item],
children: {}
}
}
},
"subgroup2": {
items: [],
children: {}
}
}
}
Here is a function that i use often. It's easily modifiable to do many recursive tasks. For example if you add a bail flag you can quickly get the stack or add a callback function that makes it even more general. Anyway that's my 2 cents
var recursiveObjMap = (function(){
var stack = [];
var result = [];
// var bail = false;
return function map(data, key){
if (!$.isArray(data) && !$.isPlainObject(data) ) {
result.push(data);
return false
}
$.each(data, function(i, v){
if (key) stack.push(key);
map(v, i);
stack.pop();
});
return result;
};
})();
recursiveObjMap({a:'b',c:{d:{e:"f"}}}) // ['b', 'f']
const obj = [
{
count: 1,
entity: "Company",
Company: [
{
entity: "Ford Motor Co",
Ford_Motor_Co: [
{
count: 1,
entity: "Ford",
},
],
},
],
},
{
count: 4,
entity: "Country",
Country: [
{
entity: "Germany",
Germany: [
{
count: 1,
entity: "Germany",
},
],
currency: "Euro (EUR)",
},
{
entity: "Italy",
Italy: [
{
count: 1,
entity: "Italy",
},
],
currency: "Euro (EUR)",
},
{
entity: "Japan",
Japan: [
{
count: 1,
entity: "Japan",
},
],
currency: "Yen (JPY)",
},
{
entity: "South Korea",
South_Korea: [
{
count: 1,
entity: "South Korea",
},
],
currency: "Won (KRW)",
},
],
},
{
count: 5,
entity: "Persons",
Persons: [
{
count: 2,
entity: "Dodge",
},
{
count: 1,
entity: "Dodge Avenger",
},
{
count: 1,
entity: "Major League",
},
{
count: 1,
entity: "Sterling Heights",
},
],
},
];
function test(runObj) {
for (let i in runObj) {
typeof runObj[i] == "object" ? test(runObj[i]) : console.log(runObj[i]);
}
}
test(obj);

Categories

Resources