สมมติว่ามีอาร์เรย์ของอาร์เรย์ที่มีข้อมูลชื่อและอีเมลของคนบางคนดังนี้:
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' ]
]