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"
    }

];
3
  • @YuryTarabanko in your deleted answer you need to put localUsers after apiUsers in the Map in order for overriding to work the way OP wants. Commented Jan 10, 2019 at 15:29
  • @PatrickRoberts The order would be different then ;) id: 1 would be the last one Commented Jan 10, 2019 at 15:36
  • You're assuming the order matters. They haven't explicitly said that :P Commented Jan 10, 2019 at 15:37

6 Answers 6

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

Sign up to request clarification or add additional context in comments.

4 Comments

This would be cool, thanks! I'll try it and get back to you if it works for me as I need it. @quirimmo
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).
@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 :)
This helped a lot! It's the most leaner and efficient solution. Thanks :)
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; }

Comments

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

Comments

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

Comments

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)
    

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.