假设我们有一个数组数组,其中包含有关像这样的某些人的姓名和电子邮件的信息-
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 output = [ ["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], ["John", "johnnybravo@mail.com"], ["Mary", "mary@mail.com"] ];
为此的代码将是-
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));
输出结果
控制台中的输出将是-
[ [ 'John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com' ], [ 'John', 'johnnybravo@mail.com' ], [ 'Mary', 'mary@mail.com' ] ]