Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

รวมซับอาร์เรย์ใน JavaScript

สมมติว่ามีอาร์เรย์ของอาร์เรย์ที่มีข้อมูลชื่อและอีเมลของคนบางคนดังนี้:

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' ]
]