[Medium] 手写 consolidateData(整合数据)

2024年3月8日

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

题目描述

假设你正在开发一款阅读 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+ 成长计划看到。如果想练习更多题目,推荐可以到 GreatFrontEnd 上练习

解法

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 上追蹤我們