Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to merge array of objects present in an array and remove duplicates?

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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading