Home > front end >  Get duplicate object array into new array form
Get duplicate object array into new array form

Time:12-10

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
},[]);
  • Related