Мне нужно объединить два массива объектов:
const local: [
{id: 1, balance: 2200, ref: 'A'},
{id: 2, balance: 2100, ref: 'C'}
]
const remote: [
{id: 1, balance: 3300, ref: 'B'},
]
Мне нужно объединить эти массивы, так что любые два объекта с одинаковым идентификатором объединяются — сохраняя один и тот же идентификатор, сохраняя баланс от remote
и объединяя их значения ref
, поэтому идеальным результатом этого примера будет:
[
{ id: 1, balance: 3300, text: 'A / B' },
{ id: 2, balance: 2100, text: 'C' }
]
Как бы я это сделал? Я пробовал следующее:
function mergeFunc(remoteArray, localArray) {
const newArray = [];
//loop over one of the arrays
for (const localObj of localArray) {
//for each iteration, search for object with matching id in other array
if (remoteArray.some(remoteObj => remoteObj.id === localObj.id)){
//if found matching id, fetch this other object
const id:matchingRemoteObj = remoteArray.find(item => item.id === localObj.id);
//create new, merged, object
const newObj = {id:matchingRemoteObj.id, balance: id:matchingRemoteObj.balance, text:`${localObj.text} / ${id:matchingRemoteObj.text}`}
//push new value to array
newArray.push(newObj);
}
}
return newArray;
}
Проблема в том, что это решение дает мне массив объединенных объектов с совпадающими идентификаторами. Мне нужен массив со всеми объектами, объединяющий только те, у которых совпадают идентификаторы...
@NickParsons да, удаленный и локальный - это независимые массивы, которые необходимо время от времени «синхронизировать» - и объединять. В объединенном выводе должны быть все уникальные объекты из обоих массивов и объединенные объекты, идентификаторы которых совпадают...
Причина в коде ниже, вы просто отправляете записи совпадений, которые вызывают эту проблему.
if (remoteArray.some(remoteObj => remoteObj.id === localObj.id))
Ниже приведена ссылка для вас с использованием Array.map()
и Array.find()
const local = [
{id: 1, balance: 2200, ref: 'A'},
{id: 2, balance: 2100, ref: 'C'}
]
const remote = [
{id: 1, balance: 3300, ref: 'B'},
]
let result = local.map(e =>{
let r = remote.find(i => i.id === e.id)
let ref = r?.ref
if (ref){
e.balance = r.balance
e.ref += ' / ' + ref
}
return e
})
console.info(result)
Обновление: если вы хотите, чтобы ваш исходный код работал, вам нужно добавить блок else
, если совпадения нет.
const local = [
{id: 1, balance: 2200, ref: 'A'},
{id: 2, balance: 2100, ref: 'C'}
]
const remote = [
{id: 1, balance: 3300, ref: 'B'},
]
function mergeFunc(remoteArray, localArray) {
const newArray = [];
//loop over one of the arrays
for (const localObj of localArray) {
//for each time, search for object with matching id in other array
if (remoteArray.some(remoteObj => remoteObj.id === localObj.id)){
//if found matching id, fetch this other object
const matchingRemoteObj = remoteArray.find(item => item.id === localObj.id);
//create new, merged, object
const newObj = {id:matchingRemoteObj.id, balance: matchingRemoteObj.balance, text:`${localObj.ref} / ${matchingRemoteObj.ref}`}
//push new value to array
newArray.push(newObj);
}else{
// this will add not match record into result array
newArray.push(localObj)
}
}
return newArray;
}
let result = mergeFunc(remote,local)
console.info(result)
Вы можете использовать методы array.map и array.find,
Чтобы заменить баланс матча удаленным массивом, который вы можете использовать,
obj.balance = o.balance
Чтобы объединить строку ссылки соответствующего идентификатора, вы можете использовать
obj.ref = `${obj.ref} / ${o.ref}`
Рабочий фрагмент:
const local = [
{ id: 1, balance: 2200, ref: "A" },
{ id: 2, balance: 2100, ref: "C" },
];
const remote = [{ id: 1, balance: 3300, ref: "B" }];
const result = local.map((obj) => {
remote.find((o) => {
if (o.id === obj.id) {
obj.balance = o.balance;
obj.ref = `${obj.ref} / ${o.ref}`;
}
});
return obj;
});
console.info(result);
Могут ли в
remote
быть объекты с идентификаторами, которых нет вlocal
? Если да, следует ли включать эти объекты в вывод?