对象数组合并

59 阅读1分钟

前言

这是最近在面试时被问到的一道题。

说难也不难,说简单也不是很简单。

我只记得当时的紧张让我大脑宕机了可能有十五分钟。

回到家后又重新整理思路写出来的。

刷过一点点算法,所以这只是鄙人自己的思路。可能不是最优解,如果看到这篇文章的小伙伴有更好的答案,欢迎评论区告诉我。

题目

给你两个对象数组arr、arr2,数组中每一项都是一个对象。对象包含内容有id、name、time三个属性。要求合并这两个数组,如果数组中id相同,则取time属性值更大的那一个。

  • 保证两个数组中相同id的time属性不相等;
  • 保证每个数组中的id不重复,是唯一的;
  • 保证每个数组中的对象是按id从小到大给的;
  • 合并后的数组中对象要按照从小到大排列。

示例


// 输入
const arr = [
  {
    id: 0,
    name: 'Zero',
    time: '0',
  },
  {
    id: 1,
    name: 'Alice',
    time: '3',
  },
  {
    id: 2,
    name: 'Jack',
    time: '3',
  },
  {
    id: 3,
    name: 'Fuck',
    time: '3',
  },
  {
    id: 6,
    name: 'six',
    time: '6',
  },
];

const arr2 = [
  {
    id: 1,
    name: 'Sam',
    time: '1',
  },
  {
    id: 2,
    name: 'Boston',
    time: '5',
  },
  {
    id: 3,
    name: 'White',
    time: '2',
  },
  {
    id: 4,
    name: 'Tong',
    time: '2',
  },
];

// 输出
[
  { id: 0, name: 'Zero', time: '0' },
  { id: 1, name: 'Alice', time: '3' },
  { id: 2, name: 'Boston', time: '5' },
  { id: 3, name: 'Fuck', time: '3' },
  { id: 4, name: 'Tong', time: '2' },
  { id: 6, name: 'six', time: '6' }
]

我的解答方式

function arrayObjectMerge(originArr, targetArr) {
  const originObj = Object.create(null);
  const targetObj = Object.create(null);
  const resObj = Object.create(null);

  originArr.forEach(
    (obj) => (originObj[obj.id] = { isCompare: false, o: obj })
  );
  targetArr.forEach((obj) => (targetObj[obj.id] = obj));

  Object.keys(targetObj).forEach((key) => {
    if (originObj[key]) {
      originObj[key].isCompare = true;
      if (Number(targetObj[key].time) > Number(originObj[key].o.time)) {
        resObj[key] = targetObj[key];
      } else {
        resObj[key] = originObj[key].o;
      }
    } else {
      resObj[key] = targetObj[key];
    }
  });

  Object.keys(originObj).map((key) => {
    if (!originObj[key].isCompare) {
      resObj[key] = originObj[key].o;
    }
  });

  return Object.values(resObj);
}

console.log(arrayObjectMerge(arr, arr2));