Home > Mobile >  Merging arrays of objects with a common key but different structure
Merging arrays of objects with a common key but different structure

Time:09-16

I'm working this problem in Typescript and I've been struggling with for a little bit of time now, and was hoping that the kind users of StackOverflow could help :)

Given the two array structures:

var localUsers = [{
    firstName: "Joe", 
    lastName: "Bloggs", 
    id: "44c021ab-be92-409b-99ad-4c3fe61d894a"
}, {
    firstName: "Pete", 
    lastName: "Doe", 
    id: "017b4dab-d58b-475e-ab31-6363d9de25c0"
}, {
    firstName: "Andy", 
    lastName: "NotRemote", 
    id: "2233e4cb-d324-463d-9a42-24b1b4cd3e11"
}]

//Above array is used for a database lookup

var remoteUsers = [{ 
    id: "44c021ab-be92-409b-99ad-4c3fe61d894a",
    timestamp: "2017-07-01T12:00:00.000"
}, {
    id: "017b4dab-d58b-475e-ab31-6363d9de25c0",
    timestamp: "2017-07-01T13:30:00.000"
}]

I want to merge these arrays via the id key, all keys in remoteUsers will have a match in localUsers, but the opposite is not always true. This should give an output similar to:

var allUsers = [{
    firstName: "Joe", 
    lastName: "Bloggs", 
    id: "44c021ab-be92-409b-99ad-4c3fe61d894a",
    timestamp: "2017-07-01T12:00:00.000"
}, {
    firstName: "Pete", 
    lastName: "Doe", 
    id: "017b4dab-d58b-475e-ab31-6363d9de25c0",
    timestamp: "2017-07-01T13:30:00.000"
}, {
    firstName: "Andy", 
    lastName: "NotRemote", 
    id: "2233e4cb-d324-463d-9a42-24b1b4cd3e11",
    timestamp: null
}]

I don't have access to libraries such as underscore or lodash for the time being.

Thank you for taking the time to help!

CodePudding user response:

Merge them with map function

let localUsers = [{ firstName: "Joe", lastName: "Bloggs", id: "44c021ab-be92-409b-99ad-4c3fe61d894a" }, { firstName: "Pete", lastName: "Doe", id: "017b4dab-d58b-475e-ab31-6363d9de25c0" }, { firstName: "Andy", lastName: "NotRemote", id: "2233e4cb-d324-463d-9a42-24b1b4cd3e11" }]
let remoteUsers = [{ id: "44c021ab-be92-409b-99ad-4c3fe61d894a", timestamp: "2017-07-01T12:00:00.000" }, { id: "017b4dab-d58b-475e-ab31-6363d9de25c0", timestamp: "2017-07-01T13:30:00.000" }]

localUsers = localUsers.map(itm => Object.assign(itm, {timestamp: remoteUsers.find(ru => ru.id == itm.id)?.timestamp}))
console.log(localUsers)

CodePudding user response:

This is something that I quickly came up with not optimized but does the job. Hope this helps. Answer from Saeed looks better.

function containsID(id, list) {
    var i;
    for (i = 0; i < list.length; i  ) {
        if (list[i].id === id) {
            return list[i];
        }
    }

    return false;
}

function mergeUsers(local, remote){
    var allUsers = []
    for (const user of local) {
        var isContainsID = containsID(user.id, remote);
        
        allUsers.push({
            firstName: user.firstName,
            lastName: user.lastName,
            id: user.id,
            timestamp: isContainsID.id || null
        });
    }
    return allUsers;
}

CodePudding user response:

You can do:

const localUsers = [{ firstName: "Joe", lastName: "Bloggs", id: "44c021ab-be92-409b-99ad-4c3fe61d894a" }, { firstName: "Pete", lastName: "Doe", id: "017b4dab-d58b-475e-ab31-6363d9de25c0" }, { firstName: "Andy", lastName: "NotRemote", id: "2233e4cb-d324-463d-9a42-24b1b4cd3e11" }]
const remoteUsers = [{ id: "44c021ab-be92-409b-99ad-4c3fe61d894a", timestamp: "2017-07-01T12:00:00.000" }, { id: "017b4dab-d58b-475e-ab31-6363d9de25c0", timestamp: "2017-07-01T13:30:00.000" }]


const removeUsersObject = remoteUsers.reduce((a, c) => (a[c.id]= c, a), {})
const result = localUsers.map(u => ({ 
  ...u,
  timestamp: null,
  ...removeUsersObject[u.id],
}))

console.log(result)

  • Related