3

I wanna merge two arrays of objects but I want to skip the objects that has the same ID (i want to save only first object that has same id).

One array is stored locally and the other I'm fetching users from 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"
    }
];

I expect to get this. The object in apiUsers with the id: 2 is skipped, because he already exist in the localUsers array of objects. I want to do this to all the objects with the same 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"
    }

];
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Milos Petrovic
  • 183
  • 1
  • 2
  • 9

6 Answers6

3

Create your mergedUsers concatenating localUsers and the apiUsers that are not in localUsers already:

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
  • 9,800
  • 3
  • 30
  • 45
  • This would be cool, thanks! I'll try it and get back to you if it works for me as I need it. @quirimmo – Milos Petrovic Jan 10 '19 at 15:38
  • Since you're not actually using the "found" object, instead of `!localUsers.find(b => b.id === a.id)`, you can use `localUsers.every(b => b.id !== a.id)`. – Jordan Running Jan 10 '19 at 16:09
  • @jordanrunning yeah thanks makes sense, even if there is not computational difference, actually you already get back a boolean. Feel free to edit it I am by phone now :) – quirimmo Jan 10 '19 at 16:15
  • This helped a lot! It's the most leaner and efficient solution. Thanks :) – Milos Petrovic Jan 10 '19 at 16:24
1

You could take a Map by reducing the arrays in the wanted order.

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; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

First remove all instance from apiUsers that exist in localUsers, then add that array to localUsers. The order of the array does not matter here as not stated in the question, but easy to perform.

const filteredApiUsers = apiUsers.filter(x => !localUsers.some(y => x.id === y.id));
const mergedUsers = [...localUsers, ...filteredApiUsers];
tic
  • 2,484
  • 1
  • 21
  • 33
0

you can use this to combine the two objects with duplicates:

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

then you can remove duplicates with the new object.

reference : Merge 2 arrays of objects

Omkar
  • 340
  • 3
  • 14
0
  1. Filter out users from apiUserArray that are already in the localUserArray.
  2. Merge both arrays.

    let distinctApiUsers = apiUsers
                            .filter(rUser => localUsers
                                              .findIndex(lUser => lUser.id == rUser.id) == -1)
    
    let mergedArray = localUsers.concat(distinctApiUsers)
    
ThatBrianDude
  • 2,952
  • 3
  • 16
  • 42
0

It's easy enough to write your own comparison function:


    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));