Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove duplicates from Array of Array (nested array of objects)

I have an Array which holds another Array of objects. I would like to remove the duplicates in this array of array.

var arr1 = [{
     child: [{name: "google", check: false}, {name: "yahoo", check: false}]
    },
    {
     child: [{name: "excite", check: false}, {name: "facebook", check: false}]
    },
    {
     child: [{name: "something1", check: false}, {name: "something2", check: false}]
    }
]

var arr2 = [{
     child: [{name: "google", check: true}, {name: "yahoo", check: false}]
    },
    {
     child: [{name: "excite", check: false}, {name: "facebook", check: false}]
    } 
]

var arr3 = [{
     child: [{name: "google", check: true}, {name: "yahoo", check: false}]
    },
    {
     child: [{name: "excite", check: false}, {name: "facebook", check: false}]
    },
    {
     child: [{name: "something1", check: false}, {name: "something2", check: false}]
    }
]

I would like to remove {name: "google", check: false} from the second child array as there is already one with same name and check: true in arr1.

Below is something what i have tried.

function mergeAndRemoveDuplicates(arr1, arr2) {

    return arr1.map(function(child) {
        return child.some(function(children) {
            return arr2.map(function(child2) {
                return child2.some(function(children2) {
                    return children.name === children2.name &&
                        children.check === true;
                });
            })
        })
    })
}

console.log(mergeAndRemoveDuplicates(arr1, arr2));

http://jsfiddle.net/g7rvbpf3/

like image 333
Thalapathy Avatar asked Aug 10 '26 07:08

Thalapathy


2 Answers

You could create a set of checked names and recursively filter the arrays:

const dupes = new Set;

for(const el of arr1.concat(arr2))
  el.child = el.child.filter(el => {
     const dupe = dupes.has(el.name);
     if(el.check) dupes.add(el.name);
     return !dupe;
  });

This will also filter duplicates in arr1, if that isn't wanted you could use arr1 to build up the set, and filter arr2:

 const dupes = new Set;

 for(const child of arr1.flatMap(it => it.child))
   if(child.checked) dupes.add(child.name);

for(const el of arr2)
 el.child = el.child.filter(it => !dupes.has(it.name));

To get one array at the end (I guess thats what you mean with "merge") you could just .concat one to the other.

like image 69
Jonas Wilms Avatar answered Aug 11 '26 19:08

Jonas Wilms


Understanding that you want to update the check properties of the elements in arr1 based on the new upcoming data from arr2, one possible approach can be to first create a hash table between the new upcoming name and check values. For this part we use Array.reduce(). The second part of the approach consiste of Array.map() the elements of the arr1 to hold the new updates.

var arr1 = [
    {
     child: [{name: "google", check: false}, {name: "yahoo", check: false}]
    },
    {
     child: [{name: "excite", check: false}, {name: "facebook", check: false}]
    },
    {
     child: [{name: "something1", check: false}, {name: "something2", check: false}]
    }
];

var arr2 = [
    {
     child: [{name: "google", check: true}, {name: "yahoo", check: false}]
    },
    {
     child: [{name: "excite", check: false}, {name: "facebook", check: false}]
    } 
];

let upHashTable = arr2.reduce((acc, {child}) =>
{
    child.forEach(({name, check}) => acc[name] = check);
    return acc;
}, {});

console.log("HashTable with updates: ", upHashTable);

let updated = arr1.map(({child}) =>
{
    return {child: child.map(o =>
    {
        o.check = upHashTable.hasOwnProperty(o.name) ? upHashTable[o.name] : o.check;
        return o;
    })};
});

console.log("Updated arr1 is: ", updated);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Note this will only update values on arr1 and will not insert any new elements on it.

like image 33
Shidersz Avatar answered Aug 11 '26 19:08

Shidersz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!