I have a nested array of objects which contains some duplicate values:
[
[
{
name: 'name1',
email: 'email1'
},
{
name: 'name2',
email: 'email2'
}
],
[
{
name: 'name1',
email: 'email1'
}
],
[
{
name: 'name1',
email: 'email1'
},
{
name: 'name2',
email: 'email2'
}
]
]
I want to create a new single array from this data containing only the objects that exist in all the nested arrays:
[
{
name: 'name1',
email: 'email1'
}
]
I have tried the following code:
const filteredArray = arrays.shift().filter(function (v) {
return arrays.every(function (a) {
return a.indexOf(v) !== -1;
});
});
console.log('filteredArray => ', filteredArray);
and:
const filteredArray = arrays.reduce((p,c) => p.filter(e => c.includes(e)));
console.log('filteredArray => ', filteredArray);
However these both only return an empty array.
Would really appreciate any help. TIA
CodePudding user response:
You could create a Map with objects from the first subarray, keyed by their JSON representation (after ordering their keys). Then filter the next subarray for objects whose JSON representation is in that map, and put those in a new map. Continue like that for all subarrays. Finally return the values that remain in the last map:
// Helper functions:
const str = o => JSON.stringify(Object.keys(o).sort().map(key => [key, o[key]]));
const mapify = arr => new Map(arr.map(o => [str(o), o]));
const intersection = data => !data.length ? [] :
[...data.slice(1).reduce((map, arr) =>
mapify(arr.filter(o => map.get(str(o)))),
mapify(data[0])).values()];
const data = [[{name: 'name1',email: 'email1'},{name: 'name2',email: 'email2'}],[{name: 'name1',email: 'email1'}],[{name: 'name1',email: 'email1'},{name: 'name2',email: 'email2'}]]
console.log(intersection(data));