Объединение массивов объектов с общим ключом, но другой структурой

#javascript #arrays #typescript #object

Вопрос:

Я работаю над этой проблемой в Typescript и уже некоторое время борюсь с ней и надеялся, что добрые пользователи StackOverflow смогут помочь 🙂

Учитывая две структуры массива:

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

Я хочу объединить эти массивы с помощью id ключа, все ключи remoteUsers будут совпадать localUsers , но не всегда верно обратное. Это должно дать результат, аналогичный:

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

В настоящее время у меня нет доступа к таким библиотекам, как подчеркивание или lodash.

Спасибо, что нашли время помочь!

Комментарии:

1. Подчеркивание и Lodash являются открытым исходным кодом, и код читаем. Если вы знаете, как решить эту проблему с помощью этих библиотек, вы можете скопировать необходимые функции в свой код.

2. Привет @brexite, какую версию js вы используете?

3. Привет @brexite, попробуйте привести пример того, что вы сделали до сих пор

Ответ №1:

Объедините их с map помощью функции

 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) 

Комментарии:

1. Это сработало прекрасно, большое вам спасибо!

Ответ №2:

Это то, что я быстро придумал, не оптимизировано, но выполняет свою работу. Надеюсь, это поможет. Ответ от Саида выглядит лучше.

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

Ответ №3:

Вы можете сделать:

 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)