I am trying to solve a problem in Angular 7, where i need to write a function that takes two array of objects, in this case, the first one and the second one, and returns the third array.
The third array is very similar to the first array, but the value of the count
key in the children
array is dependent on whether there are any children
in the second array or if present, reflect the value of count
in that object. Is there an array map function in angular that can solve this?
First array:
[
{
"name": "Category 1",
"value": "Vegetables",
"children": [
{"name": "Carrots", "value": "Carrots", "count": 2},
{"name": "Peas", "value": "Peas", "count": 1}
]
},
{
"name": "Category 2",
"value": "Fruits",
"children": [
{"name": "Apples", "value": "Apples", "count": 10},
{"name": "Bananas", "value": "Bananas", "count": 5}
]
},
{
"name": "Category 3",
"value": "Desserts",
"children": [
{"name": "Ice Cream", "value": "IceCream", "count": 3},
{"name": "Cakes", "value": "Cakes", "count": 3}
]
}
]
Second array
[
{
"name": "Category 1",
"value": "Vegetables",
"children": [
{"name": "Peas", "value": "Peas", "count": 1}
]
},
{
"name": "Category 2",
"value": "Fruits",
"children": [
{"name": "Apples", "value": "Apples", "count": 3},
{"name": "Bananas", "value": "Bananas", "count": 2}
]
},
{
"name": "Category 3",
"value": "Desserts",
"children": []
}
]
Third array
[
{
"name": "Category 1",
"value": "Vegetables",
"children": [
{"name": "Carrots", "value": "Carrots", "count": 0},
{"name": "Peas", "value": "Peas", "count": 1}
]
},
{
"name": "Category 2",
"value": "Fruits",
"children": [
{"name": "Apples", "value": "Apples", "count": 3},
{"name": "Bananas", "value": "Bananas", "count": 2}
]
},
{
"name": "Category 3",
"value": "Desserts",
"children": [
{"name": "Ice Cream", "value": "IceCream", "count": 0},
{"name": "Cakes", "value": "Cakes", "count": 0}
]
}
]
You can do this quite simply with map
and find
, then reduce
the array afterwards.
const arr1 = [{"name":"Category 1","value":"Vegetables","children":[{"name":"Carrots","value":"Carrots","count":2},{"name":"Peas","value":"Peas","count":1}]},{"name":"Category 2","value":"Fruits","children":[{"name":"Apples","value":"Apples","count":10},{"name":"Bananas","value":"Bananas","count":5}]},{"name":"Category 3","value":"Desserts","children":[{"name":"Ice Cream","value":"IceCream","count":3},{"name":"Cakes","value":"Cakes","count":3}]}]; const arr2 = [{"name":"Category 1","value":"Vegetables","children":[{"name":"Peas","value":"Peas","count":1}]},{"name":"Category 2","value":"Fruits","children":[{"name":"Apples","value":"Apples","count":3},{"name":"Bananas","value":"Bananas","count":2}]},{"name":"Category 3","value":"Desserts","children":[]}]; const res = arr1.map(({ name, value, children }) => { let found = arr2.find(({ name: n, value: v }) => n == name && v == value); if (found) children = children.concat(found.children).reduce((a, c) => { let f = a.findIndex(({ name: n }) => n == c.name); if (f > -1) a[f].count += c.count; else a.push(c); return a; }, []); return { name, value, children }; }); console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }
Here idea is
const arr1 = [{"name":"Category 1","value":"Vegetables","children":[{"name":"Carrots","value":"Carrots","count":2},{"name":"Peas","value":"Peas","count":1}]},{"name":"Category 2","value":"Fruits","children":[{"name":"Apples","value":"Apples","count":10},{"name":"Bananas","value":"Bananas","count":5}]},{"name":"Category 3","value":"Desserts","children":[{"name":"Ice Cream","value":"IceCream","count":3},{"name":"Cakes","value":"Cakes","count":3}]}]; const arr2 = [{"name":"Category 1","value":"Vegetables","children":[{"name":"Peas","value":"Peas","count":1}]},{"name":"Category 2","value":"Fruits","children":[{"name":"Apples","value":"Apples","count":3},{"name":"Bananas","value":"Bananas","count":2}]},{"name":"Category 3","value":"Desserts","children":[]}]; let arr2Obj = Object.fromEntries(arr2.map(val => [val.name, val])) const res = arr1.map(({ name, value, children }) => { let arr2Children = ( arr2Obj[name] || {} ).children let childrenObj = Object.fromEntries(arr2Children.map(val => [val.name,val])) let newChildren = children.map( val => { let count = (childrenObj[val.name] || {}).count || 0 return {...val,count} }) return {name,value,children:newChildren} }); console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }
PS:- If your array1 and array2 are always in sorted manner than you need not to change it object and you can directly access using index, same for the children
const arr1 = [{"name":"Category 1","value":"Vegetables","children":[{"name":"Carrots","value":"Carrots","count":2},{"name":"Peas","value":"Peas","count":1}]},{"name":"Category 2","value":"Fruits","children":[{"name":"Apples","value":"Apples","count":10},{"name":"Bananas","value":"Bananas","count":5}]},{"name":"Category 3","value":"Desserts","children":[{"name":"Ice Cream","value":"IceCream","count":3},{"name":"Cakes","value":"Cakes","count":3}]}]; const arr2 = [{"name":"Category 1","value":"Vegetables","children":[{"name":"Peas","value":"Peas","count":1}]},{"name":"Category 2","value":"Fruits","children":[{"name":"Apples","value":"Apples","count":3},{"name":"Bananas","value":"Bananas","count":2}]},{"name":"Category 3","value":"Desserts","children":[]}]; let createObject = (arr) => arr.reduce((op,[key,value])=>{ op[key] = value return op },{}) let arr2Obj = createObject(arr2.map(val => [val.name, val])) const res = arr1.map(({ name, value, children }) => { let arr2Children = ( arr2Obj[name] || {} ).children let childrenObj = createObject(arr2Children.map(val => [val.name,val])) let newChildren = children.map( val => { let count = (childrenObj[val.name] || {}).count || 0 return {...val,count} }) return {name,value,children:newChildren} }); console.log(res);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.