Merging subarrays in JavaScript

JavascriptWeb DevelopmentFront End TechnologyObject Oriented Programming

Suppose, we have an array of arrays that contains information about the name and email of some people like this −

const arr = [
   ["John", "johnsmith@mail.com", "john00@mail.com"],
   ["John", "johnnybravo@mail.com"],
   ["John", "johnsmith@mail.com", "john_newyork@mail.com"],
   ["Mary", "mary@mail.com"]
];

Each element of the array is a subarray of strings, where the first element is a name, and the rest of the elements are emails belonging to that name.

Now, we would like to merge these subarrays. Two subarrays definitely belong to the same person if there is some email that is common to both subarrays.

Note that even if two subarrays have the same name, they may belong to different people as people could have the same name.

A person can have any number of accounts initially, but all of their accounts definitely have the same name.

After merging the subarrays, we need to return them in the following format − the first element of each subarray is the name, and the rest of the elements are emails in sorted order. The subarrays themselves can be returned in any order.

Therefore, for the above array, the output should look like −

const output = [
   ["John", 'john00@mail.com', 'john_newyork@mail.com',
   'johnsmith@mail.com'],
   ["John", "johnnybravo@mail.com"],
   ["Mary", "mary@mail.com"]
];

Example

The code for this will be −

const arr = [
   ["John", "johnsmith@mail.com", "john00@mail.com"],
   ["John", "johnnybravo@mail.com"],
   ["John", "johnsmith@mail.com", "john_newyork@mail.com"],
   ["Mary", "mary@mail.com"]
];
const recusiveMatch = (included, i, tmp, arr, res) => {
   for(let j = 1; j < arr[i].length; j += 1) {
      let currentEmail = arr[i][j];
      if(included.has(currentEmail)) continue;
      res.push(currentEmail);
      included.add(currentEmail);
      let currentAccountIndexes = tmp.get(currentEmail);
      for(let c = 0; c < currentAccountIndexes.length; c += 1) {
         let currentIndex = currentAccountIndexes[c];
         if(i !== currentIndex) {
            recusiveMatch(included, currentIndex, tmp, arr, res);
         }
      }
   }
};
const merge = (arr) => {
   const tmp = new Map(),
   included = new Set(),
   res = [];
   arr.forEach((account, i) => {
      for(let u = 1; u < account.length; u += 1) {
         let currentEMail = account[u];
         tmp.set(currentEMail, tmp.get(currentEMail) || []);
         tmp.get(currentEMail).push(i);
      }
   });
   arr.forEach((account, i) => {
      if(!included.has(arr[1])) {
         let u = [];
         recusiveMatch(included, i, tmp, arr, u);
         if(u.length) {
            res.push(u);
            u.sort();
            u.unshift(account[0]);
         }
      }
   });
   return res;
};
console.log(merge(arr));

Output

And the output in the console will be −

[
   [
      'John',
      'john00@mail.com',
      'john_newyork@mail.com',
      'johnsmith@mail.com'
   ],
   [ 'John', 'johnnybravo@mail.com' ],
   [ 'Mary', 'mary@mail.com' ]
]
raja
Published on 23-Nov-2020 12:12:13
Advertisements