I have an array like this:
var myArray = [
{
"name": "walkway_lights",
"title": "Brilliance Sequoia Pathlight",
"subCat": "Area & Pathway Lights",
"cat": "Fixture-Speaker-Sub",
"msrp": 599,
"accTotal": 50,
"purchasePrice": 222.35,
"totalPrice": 1222,
"totalPurchasePrice": 468.7,
"lightShadowColor": "warmWhite",
"wattage": {
"key": "-Mm46mr5KHJwLXsucsJK",
"upPrice": 12,
"value": "3.5w G4"
},
"selectedAccessory": [
{
"key": "-Mxa9Jt-9si0Bw7Zhj1S",
"name": "Demo 1",
"price": 5
},
{
"key": "-Mxa9NUjMExUd8b5UgfU",
"name": "Demo 2",
"price": 10
},
{
"key": "-Mxa9Vh4yBK9j-GNpA0v",
"name": "Demo 4",
"price": 20
}
],
"beam": {
"key": "-Mm4B0FO34Ineht5O0sw",
"value": "360"
}
},
{
"name": "walkway_lights",
"title": "Brilliance Sequoia Pathlight",
"type": "group",
"subCat": "Area & Pathway Lights",
"cat": "Fixture-Speaker-Sub",
"msrp": 599,
"accTotal": 15,
"purchasePrice": 222.35,
"totalPrice": 626,
"totalPurchasePrice": 249.35,
"lightShadowColor": "warmWhite",
"wattage": {
"key": "-Mm46mr5KHJwLXsucsJK",
"upPrice": 12,
"value": "3.5w G4"
},
"selectedAccessory": [
{
"key": "-Mxa9Jt-9si0Bw7Zhj1S",
"name": "Demo 1",
"price": 5
},
{
"key": "-Mxa9NUjMExUd8b5UgfU",
"name": "Demo 2",
"price": 10
},
,
{
"key": "-Mxa9ZUjMExUd3g5Ugfs",
"name": "Demo 3",
"price": 15
}
],
"beam": {
"key": "-Mm4B0FO34Ineht5O0sw",
"value": "360"
}
}
]
I need to reformat “myArray” in such a way that it nest all objects based “subCat” and then “subCat” inside “cat”. In those nested children, I am converting duplicate objects based on “name + lightShadowColor + wattage.value + beam.value” and I am adding a variable “count” to remove duplicate objects. I am able to come up with a solution like below:
let result = [], counter = {};
for (let item of myArray) {
let countId;
if(item.lightShadowColor && item.wattage) {
countId = item.name + item.lightShadowColor + item.wattage.value + item.beam.value
} else {
countId = item.name
}
let a = [];
if (counter[countId]) {
counter[countId].count++;
counter[countId].totalPrice = counter[countId].count * (counter[countId].msrp + counter[countId].wattage.upPrice)
counter[countId].totalPurchasePrice = counter[countId].count * (counter[countId].purchasePrice + counter[countId].wattage.upPrice);
continue
}
let cat = result.find(o => o.cat == item.cat);
if (!cat) result.push(cat = { cat: item.cat, children: [] });
let subCat = cat.children.find(o => o.subCat == item.subCat);
if (!subCat) cat.children.push(subCat = { subCat: item.subCat, children: [] });
item.count = 1;
subCat.children.push(counter[countId] = item);
}
console.log(result)
The above code gives me output which I desire as below:
result = [
{
"cat": "Fixture-Speaker-Sub",
"children": [
{
"subCat": "Area & Pathway Lights",
"children": [
{
"count": 2
"name": "walkway_lights",
"title": "Brilliance Sequoia Pathlight",
"subCat": "Area & Pathway Lights",
"cat": "Fixture-Speaker-Sub",
"msrp": 599,
"accTotal": 50,
"purchasePrice": 222.35,
"totalPrice": 1222,
"totalPurchasePrice": 468.7,
"lightShadowColor": "warmWhite",
"wattage": {
"key": "-Mm46mr5KHJwLXsucsJK",
"upPrice": 12,
"value": "3.5w G4"
},
"selectedAccessory": [
{
"key": "-Mxa9Jt-9si0Bw7Zhj1S",
"name": "Demo 1",
"price": 5
},
{
"key": "-Mxa9NUjMExUd8b5UgfU",
"name": "Demo 2",
"price": 10
},
{
"key": "-Mxa9Vh4yBK9j-GNpA0v",
"name": "Demo 4",
"price": 20
}
],
"beam": {
"key": "-Mm4B0FO34Ineht5O0sw",
"value": "360"
}
}
]
}
]
}
]
Now, I am trying to figure out how should I merge “selectedAccessory” array for duplicate objects. Any idea how should I merge those keys? Inside the result, I need “selectedAccessory” array like this:
"selectedAccessory": [
//The below come from myArray first duplicate object
{
"key": "-Mxa9Jt-9si0Bw7Zhj1S",
"name": "Demo 1",
"price": 5
},
{
"key": "-Mxa9NUjMExUd8b5UgfU",
"name": "Demo 2",
"price": 10
},
{
"key": "-Mxa9Vh4yBK9j-GNpA0v",
"name": "Demo 4",
"price": 20
},
//The below come from myArray second duplicate object
{
"key": "-Mxa9Jt-9si0Bw7Zhj1S",
"name": "Demo 1",
"price": 5
},
{
"key": "-Mxa9NUjMExUd8b5UgfU",
"name": "Demo 2",
"price": 10
},
,
{
"key": "-Mxa9ZUjMExUd3g5Ugfs",
"name": "Demo 3",
"price": 15
}
],