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.
5
Answers
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 additionalfilter()
at the end to remove the empty arrays:The above uses
.map()
to transform each inner array into a filtered version of itself. Within the filter function, I’m using aSet
to keep track ofTime
andElement
pairs that have been already seen by creating a serialized version of the object in the shape ofTime$Element
. This allows us to check if the object has already been seen already, which we can then use to returntrue
/false
to keep the current element or not.If you want, you can merge the
.map().filter()
into onereduce()
call to avoid the additional iteration over the array (but this isn’t as readable in my opinion):You could take a
Set
and filter inner arrays.You can simply utilize the
Set
data structure to avoid duplicates andreduce()
to process the array.So you map the
arrays
into a new one with the child arrays reduced. For the mapping function you provide amap
variable in a closure of IIFE where we store our object keys encountered during the reducing.We use
??=
operator to add the child array items to the map if they are not in the map yet. Also we add it to the reduced array in that case. So basically an item with a new key is added to the result then items with the same key are skipped since they are already in the map and the right part of the??=
operator isn’t executed.A trick here is not make a key by concatenating item values thus making a new string (that slow) but rather make nested mapping with
??=
.Finally we filter the final array of the reduced child arrays with
length
property (it should be truthy).The code you provided does not accomplish the task because it attempts to reduce a nested array structure without flattening it and does not handle the segregation of objects based on their ‘Element’ property.
If you’re lookin’ to split up an array of objects by a common key, you can totally boss it with a combo of
reduce
andmap
. You can create a Map object to group items by their Element value and then extract the grouped items into separate arrays.The code provided below just merges the arrays, and also removes their duplicates and you achieve the desired result.
Output: