I have an array which consists of another array of objects with key value pairs. I want to merge and segregate these array of objects based on key which is common in every object. There can be n number of array of objects.
array1 = [
[
{ Time: 45, Element: 'Hi'},
{ Time: 55, Element: 'Hi' },
{ Time: 65, Element: 'Hi' }
],
[
{ Time: 45, Element: 'Hi' },
{ Time: 55, Element: 'Hi' },
{ Time: 65, Element: 'Hi' },
{ Time: 25, Element: 'Hello' },
{ Time: 35, Element: 'Hello' },
{ Time: 20, Element: 'Hello' }
],
[
{ Time: 45, Element: 'Hi' },
{ Time: 55, Element: 'Hi' },
{ Time: 65, Element: 'Hi' },
{ Time: 25, Element: 'Hello' },
{ Time: 35, Element: 'Hello' },
{ Time: 20, Element: 'Hello' },
{ Time:100, Element: 'Bye'}
]
];
What i expect from the merged array is as follows:
mergedArray = [
[
{ Time: 45, Element: 'Hi'},
{ Time: 55, Element: 'Hi' },
{ Time: 65, Element: 'Hi' }
],
[
{ Time: 25, Element: 'Hello' },
{ Time: 35, Element: 'Hello' },
{ Time: 20, Element: 'Hello' }
],
[
{ Time:100, Element: 'Bye'}
]
];
How to achieve this in Javascript?
I tried the following code
arrays = [
[
{ Time: 45, Element: 'Hi'},
{ Time: 55, Element: 'Hi' },
{ Time: 65, Element: 'Hi' }
],
[
{ Time: 45, Element: 'Hi' },
{ Time: 55, Element: 'Hi' },
{ Time: 65, Element: 'Hi' },
{ Time: 25, Element: 'Hello' },
{ Time: 35, Element: 'Hello' },
{ Time: 20, Element: 'Hello' }
],
[
{ Time: 45, Element: 'Hi' },
{ Time: 55, Element: 'Hi' },
{ Time: 65, Element: 'Hi' },
{ Time: 25, Element: 'Hello' },
{ Time: 35, Element: 'Hello' },
{ Time: 20, Element: 'Hello' },
{ Time:100, Element: 'Bye'}
]
];
const uniqueMergedArray = arrays.reduce((result, obj) => {
if (!result.some(item => item.Element === obj.Element)) {
result.push(obj);
}
return result;
}, [])
console.log("Merged Array:", uniqueMergedArray);
The above code only return the first array. Please suggest a simple method to merge the array of objects and get three different unique arrays with no duplicates.
>Solution :
The obj in your .reduce() callback represents one of your inner arrays, not the objects, and so you’re not properly iterating the inner arrays and checking the objects. I’d suggest using .map() within an inner .filter(), with an additional filter() at the end to remove the empty arrays:
const arrays = [ [{Time: 45,Element:'Hi'},{Time: 55, Element: 'Hi' },{ Time: 65, Element: 'Hi' }], [{Time: 45,Element:'Hi' }, { Time: 55, Element: 'Hi'},{Time: 65, Element: 'Hi' }, {Time: 25,Element:'Hello' }, { Time: 35, Element: 'Hello' }, { Time: 20, Element: 'Hello' }], [{Time: 45,Element:'Hi' },{ Time: 55, Element: 'Hi'},{Time: 65, Element: 'Hi' }, {Time: 25,Element:'Hello'},{Time: 35, Element: 'Hello'},{Time: 20, Element: 'Hello'}, {Time:100, Element: 'Bye'}] ];
const timeElementSet = new Set();
const uniqueMergedArray = arrays.map(arr => arr.filter(obj => {
const key = `${obj.Time}$${obj.Element}`;
if (timeElementSet.has(key)) return false;
timeElementSet.add(key);
return true;
})).filter(arr => arr.length > 0);
console.log("Merged Array:", uniqueMergedArray);
The above uses .map() to transform each inner array into a filtered version of itself. Within the filter function, I’m using a Set to keep track of Time and Element pairs that have been already seen by creating a serialized version of the object in the shape of Time$Element. This allows us to check if the object has already been seen already, which we can then use to return true/false to keep the current element or not.
If you want, you can merge the .map().filter() into one reduce() call to avoid the additional iteration over the array (but this isn’t as readable in my opinion):
const arrays = [ [{ Time: 45, Element: 'Hi' }, { Time: 55, Element: 'Hi' }, { Time: 65, Element: 'Hi' }], [{ Time: 45, Element: 'Hi' }, { Time: 55, Element: 'Hi' }, { Time: 65, Element: 'Hi' }, { Time: 25, Element: 'Hello' }, { Time: 35, Element: 'Hello' }, { Time: 20, Element: 'Hello' }], [{ Time: 45, Element: 'Hi' }, { Time: 55, Element: 'Hi' }, { Time: 65, Element: 'Hi' }, { Time: 25, Element: 'Hello' }, { Time: 35, Element: 'Hello' }, { Time: 20, Element: 'Hello' }, { Time: 100, Element: 'Bye' }] ];
const timeElementSet = new Set();
const uniqueMergedArray = arrays.reduce((acc, curr) => {
const filtered = curr.filter(obj => {
const key = `${obj.Time}$${obj.Element}`;
if (timeElementSet.has(key)) return false;
timeElementSet.add(key);
return true;
});
return filtered.length > 0 ? [...acc, filtered] : acc; // or use: if(...) acc.push(filtered); return acc;` to be more efficient
}, []);
console.log("Merged Array:", uniqueMergedArray);