[Medium] 手寫 consolidateData (整合數據)

2024年3月8日

💎 加入 E+ 成長計畫 與超過 300+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

題目描述

假設你正在開發一款閱讀 App,該 App 追蹤用戶的閱讀相關紀錄,會有以下格式記錄的資料:

const sessions = [
  { user: 8, duration: 50, books: ["The Hobbit"] },
  { user: 7, duration: 150, books: ["Pride and Prejudice"] },
  { user: 1, duration: 10, books: ["The Lord of the Rings"] },
  { user: 7, duration: 100, books: ["The Great Gatsby", "Animal Farm"] },
  { user: 7, duration: 200, books: ["The Great Gatsby"] },
  { user: 2, duration: 200, books: ["1984"] },
  { user: 2, duration: 200, books: ["The Great Gatsby"] },
];

每個物件都有以下欄位:

  • user:讀者的用戶 ID。
  • duration:閱讀的持續時間,以分鐘為單位。
  • books:閱讀的書籍標題,以陣列形式按字母排序。

現在你需要實作一個 consolidateData 函式,來合併每個用戶的閱讀資料,合併規則如下:

  1. 將相同用戶的資料合併為單一物件。
  2. 將合併的 duration 欄位相加。
  3. 合併 books 陣列,移除重複書名,並按字母順序排序。
  4. 保持結果的原始順序。
  5. 如果多筆資料屬於同一用戶,合併後的應取代原始集合中該用戶最早出現的位置。
  6. 不要修改輸入物件。

上述的範例輸入,預期會有以下輸出

[
  { user: 8, duration: 50, books: ["The Hobbit"] },
  {
    user: 7,
    duration: 450,
    books: ["Animal Farm", "Pride and Prejudice", "The Great Gatsby"],
  },
  { user: 1, duration: 10, books: ["The Lord of the Rings"] },
  { user: 2, duration: 400, books: ["1984", "The Great Gatsby"] },
];

本題解答

以下是本題的解答,詳細解題思路可以在 E+ 成長計畫看到

解法

function consolidateData(sessions) {
  const mergedData = [];
  const seenUsers = new Set();

  for (const session of sessions) {
    const userId = session.user;

    if (seenUsers.has(userId)) {
      const existingIndex = mergedData.findIndex(
        (user) => user.user === userId
      );

      mergedData[existingIndex].duration += session.duration;
      mergedData[existingIndex].books = Array.from(
        new Set([...mergedData[existingIndex].books, ...session.books])
      ).sort();
    } else {
      mergedData.push({
        user: userId,
        duration: session.duration,
        books: session.books,
      });
      seenUsers.add(userId);
    }
  }

  return mergedData;
}
🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們