【问题标题】:Merge two array of objects with skipping objects that has same ID property合并两个对象数组,跳过具有相同 ID 属性的对象
【发布时间】:2019-06-05 11:53:29
【问题描述】:

我想合并两个对象数组,但我想跳过具有相同 ID 的对象(我只想保存具有相同 ID 的第一个对象)。

一个数组存储在本地,另一个我从 API 获取用户。

const localUsers = [
    {
        "id": 1,
        "first_name": "Adam",
        "last_name": "Bent",
        "avatar": "some img url"
    },
    {
        "id": 2,
        "first_name": "New Name",
        "last_name": "New Last Name",
        "avatar": "some new img url"
    }

];

const apiUsers = [
    {
        "id": 2,
        "first_name": "Eve",
        "last_name": "Holt",
        "avatar": "some img url"
    },
    {
        "id": 3,
        "first_name": "Charles",
        "last_name": "Morris",
        "avatar": "some img url"
    }
];

我希望得到这个。 apiUsers 中id: 2 的对象被跳过,因为他已经存在于对象的localUsers 数组中。我想对所有具有相同 ID 的对象执行此操作。

const mergedUsers = [
    {
        "id": 1,
        "first_name": "Adam",
        "last_name": "Bent",
        "avatar": "some img url"
    },
    {
        "id": 2,
        "first_name": "New Name",
        "last_name": "New Last Name",
        "avatar": "some new img url"
    },
    {
        "id": 3,
        "first_name": "Charles",
        "last_name": "Morris",
        "avatar": "some img url"
    }

];

【问题讨论】:

  • @YuryTarabanko 在您删除的答案中,您需要将localUsers 之后 apiUsers 放入Map 中,以便覆盖以OP 想要的方式工作。跨度>
  • @PatrickRoberts 那么顺序会有所不同 ;) id: 1 将是最后一个
  • 您假设订单很重要。他们没有明确表示:P

标签: javascript arrays object ecmascript-6


【解决方案1】:

创建您的 mergedUsers 连接 localUsers 和已经不在 localUsers 中的 apiUsers:

const localUsers = [
    {
        "id": 1,
        "first_name": "Adam",
        "last_name": "Bent",
        "avatar": "some img url"
    },
    {
        "id": 2,
        "first_name": "New Name",
        "last_name": "New Last Name",
        "avatar": "some new img url"
    }

];

const apiUsers = [
    {
        "id": 2,
        "first_name": "Eve",
        "last_name": "Holt",
        "avatar": "some img url"
    },
    {
        "id": 3,
        "first_name": "Charles",
        "last_name": "Morris",
        "avatar": "some img url"
    }
];

const mergedUsers = localUsers.concat(apiUsers.filter(a => !localUsers.find(b => b.id === a.id)));
console.log(mergedUsers);

【讨论】:

  • 这会很酷,谢谢!如果它对我有用,我会尝试并回复你。 @quirimmo
  • 由于您实际上并没有使用“找到”对象,而不是!localUsers.find(b => b.id === a.id),因此您可以使用localUsers.every(b => b.id !== a.id)
  • @jordanrunning 是的,谢谢是有道理的,即使没有计算差异,实际上你已经得到了一个布尔值。随意编辑它我现在通过电话:)
  • 这帮助很大!这是最精简和有效的解决方案。谢谢:)
【解决方案2】:

您可以通过按所需顺序减少数组来获取Map

const
    localUsers = [{ id: 1, first_name: "Adam", last_name: "Bent", avatar: "some img url" }, { id: 2, first_name: "New Name", last_name: "New Last Name", avatar: "some new img url" }],
    apiUsers = [{ id: 2, first_name: "Eve", last_name: "Holt", avatar: "some img url" }, { id: 3, first_name: "Charles", last_name: "Morris", avatar: "some img url" }],
    result = Array.from(
        [localUsers, apiUsers]
            .reduce(
                (m, a) => a.reduce((n, o) => n.set(o.id, n.get(o.id) || o), m),
                new Map
            )
            .values()
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案3】:

    首先从apiUsers 中删除所有存在于localUsers 中的实例,然后将该数组添加到localUsers。数组的顺序在这里并不重要,因为问题中没有说明,但很容易执行。

    const filteredApiUsers = apiUsers.filter(x => !localUsers.some(y => x.id === y.id));
    const mergedUsers = [...localUsers, ...filteredApiUsers];
    

    【讨论】:

      【解决方案4】:

      您可以使用它来组合两个具有重复项的对象:

      Array.prototype.push.apply(localUsers,apiUsers);
      

      然后您可以使用新对象删除重复项。

      参考:Merge 2 arrays of objects

      【讨论】:

        【解决方案5】:
        1. 从 apiUserArray 中过滤掉已经在 localUserArray 中的用户。
        2. 合并两个数组。

          let distinctApiUsers = apiUsers
                                  .filter(rUser => localUsers
                                                    .findIndex(lUser => lUser.id == rUser.id) == -1)
          
          let mergedArray = localUsers.concat(distinctApiUsers)
          

        【讨论】:

          【解决方案6】:

          编写自己的比较函数很容易:

          
              for(var i=0; i<localUsers.length; ++i) {
                  var checked = 0;
                  for(var j=i+1; j<apiUsers.length; ++j) {
                       if(localUsers[i]['id'] === apiUsers[j]['id']){
                            apiUsers.splice(j--, 1);
                       }
                  }
              }
              console.log(localUsers.concat(apiUsers));
          
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-08-02
            • 1970-01-01
            • 2018-05-22
            • 1970-01-01
            • 2021-05-02
            • 2015-12-16
            • 1970-01-01
            相关资源
            最近更新 更多