I have an array with duplicate values which i'm able to filter it but not able to make the array childern getting duplicate values.
Thanks in advance
var array = [
['P1', 'D3', 'Cus 092', 'B-Trade-Bag', 1],
['P1', 'D2', 'Cus 092', 'B-Trade-Bag', 3],
['P1', 'D1', 'Cus 092', 'B-Trade-Bag', 6],
['P1', 'D3', 'Cus 094', 'B-Trade-Bag', 6],
['P2', 'D3', 'Cus 095', 'B-Trade-Bag', 3],
['P1', 'D2', 'Cus 094', 'B-Trade-Bag', 3],
['P1', 'D3', 'Cus 094', 'B-Trade-Bag', 3]]
var result = array.reduce((a,c) =>{
let obj = a.find(i => i.name == c[0])
if(obj){
if(obj['children'][0].name == c[1]){
obj.children[0].children.push({'name': c[2], 'value': c[4] })
} else {
obj.children.push({'name':c[1], 'children': [{ 'name': c[2], 'value': c[4] }] })
}
}else{
obj ={'name':c[0],'children':[{'name':c[1], 'children': [{ 'name': c[2], 'value': c[4] }] }] }
a.push(obj);
}
return a
},[]);
I want this array
[{"name":"P1","children":[{"name":"D3","children":[{"name":"Cus 092","value":1},{"name":"Cus 094","value":6},{"name":"Cus 094","value":3}]},{"name":"D2","children":[{"name":"Cus 092","value":3},{"name":"Cus 094","value":3}]},{"name":"D1","children":[{"name":"Cus 092","value":6}]}]},{"name":"P2","children":[{"name":"D3","children":[{"name":"Cus 095","value":3}]}]}]
but getting this array
[{"name":"P1","children":[{"name":"D3","children":[{"name":"Cus 092","value":1},{"name":"Cus 094","value":6},{"name":"Cus 094","value":3}]},{"name":"D2","children":[{"name":"Cus 092","value":3}]},{"name":"D1","children":[{"name":"Cus 092","value":6}]},{"name":"D2","children":[{"name":"Cus 094","value":3}]}]},{"name":"P2","children":[{"name":"D3","children":[{"name":"Cus 095","value":3}]}]}]
CodePudding user response:
The problem with your code is: if(obj['children'][0].name == c[1])
. You need to test all children, not just the first. Here is the fixed code:
const array = [
['P1', 'D3', 'Cus 092', 'B-Trade-Bag', 1],
['P1', 'D2', 'Cus 092', 'B-Trade-Bag', 3],
['P1', 'D1', 'Cus 092', 'B-Trade-Bag', 6],
['P1', 'D3', 'Cus 094', 'B-Trade-Bag', 6],
['P2', 'D3', 'Cus 095', 'B-Trade-Bag', 3],
['P1', 'D2', 'Cus 094', 'B-Trade-Bag', 3],
['P1', 'D3', 'Cus 094', 'B-Trade-Bag', 3]];
let result = array.reduce((a,c) => {
let obj = a.find(i => i.name == c[0])
if(obj) {
let exists = obj['children'].filter(child => child.name === c[1]);
if(exists.length) {
exists[0].children.push({'name': c[2], 'value': c[4] })
} else {
obj.children.push({'name':c[1], 'children': [{ 'name': c[2], 'value': c[4] }] })
}
}else{
obj ={'name':c[0],'children':[{'name':c[1], 'children': [{ 'name': c[2], 'value': c[4] }] }] }
a.push(obj);
}
return a
},[]);
console.log(result);
CodePudding user response:
You could take a nested grouping for the indices zero and one and push the most nested object to the childen.
This approch allows deeper nested results, if necessary.
const
data = [['P1', 'D3', 'Cus 092', 'B-Trade-Bag', 1], ['P1', 'D2', 'Cus 092', 'B-Trade-Bag', 3], ['P1', 'D1', 'Cus 092', 'B-Trade-Bag', 6], ['P1', 'D3', 'Cus 094', 'B-Trade-Bag', 6], ['P2', 'D3', 'Cus 095', 'B-Trade-Bag', 3], ['P1', 'D2', 'Cus 094', 'B-Trade-Bag', 3], ['P1', 'D3', 'Cus 094', 'B-Trade-Bag', 3]],
indices = [0, 1],
result = data.reduce((r, a) => {
indices
.reduce((q, i) => {
let o = q.find(({ name }) => name === a[i]);
if (!o) q.push(o = { name: a[i], children: [] });
return o.children;
}, r)
.push({ name: a[2], value: a[4] });
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
You needed to add additional find inside first if and push if doesn't exist. but you were checking for first item in array always. I cleaned up your code lil bit, and added the extra find. see if this helps.
let obj = a.find(i => i.name == c[0])
if(obj){
let cObj = obj.children.find(oc => oc.name === c[1]);
if(!cObj) {
cObj = {name: c[1], children: []};
obj.children.push(cObj);
};
cObj.children.push({'name': c[2], 'value': c[4] })
} else {
obj ={name:c[0],children:[] }
obj.children.push({name: c[1], children: [{name: c[2], value: c[4]}]});
a.push(obj);
}
return a
},[]);