Find and replace object in array (based on id)
Just using a simple Array.map and a method to check the other array.
const allItems = [
{
'id': 1,
'category_id': 1,
'text': 'old',
},
{
'id': 2,
'category_id': 1,
'text': 'old'
},
{
'id': 3,
'category_id': 1,
'text': 'old_same'
}
]
const newItems = [
{
'id': 1,
'category_id': 1,
'text': 'new',
'more_info': 'abcd'
},
{
'id': 2,
'category_id': 1,
'text': 'new',
'more_info': 'abcd'
}
]
const findNewItem = (oldItem) => newItems.find(item => item.id === oldItem.id);
let arr = allItems.map(item => findNewItem(item)||item);
console.log(arr);
Use Array.map
and Array.find()
:
const allItems = [
{ 'id': 1, 'category_id': 1, 'text': 'old' },
{ 'id': 2, 'category_id': 1, 'text': 'old' }
];
const newItems = [
{ 'id': 1, 'category_id': 1, 'text': 'new', 'more_info': 'abcd' },
{ 'id': 2, 'category_id': 1, 'text': 'new', 'more_info': 'abcd' }
];
const result = allItems.map(x => {
const item = newItems.find(({ id }) => id === x.id);
return item ? item : x;
});
console.log(result);
This can even be shortened by using a logical or to return the original item when the call to find
returns undefined
:
const result = allItems.map(x => newItems.find(({ id }) => id === x.id) || x);
Regarding your code, you can't use indexOf
since it only compares primitive values or references in the case of arrays and objects.
Just use map
like so:
const allItems = [{
'id': 1,
'category_id': 1,
'text': 'old',
},
{
'id': 2,
'category_id': 1,
'text': 'old'
}
];
const newItems = [{
'id': 1,
'category_id': 1,
'text': 'new',
'more_info': 'abcd'
},
{
'id': 2,
'category_id': 1,
'text': 'new',
'more_info': 'abcd'
}
];
const replacedItems = allItems.map(e => {
if (newItems.some(({ id }) => id == e.id)) {
return newItems.find(({ id }) => id == e.id);
}
return e;
});
console.log(replacedItems);
Depending on how large your input arrays are, you might consider adding an intermediate step to build a "map" of your newItems
, where the key of this map is the id
of the item.
Using a mapping such as this would allow for much faster reconciliation (and replacement) of items from the allItems
array with items in the newItems
array:
function replaceItemsOnId(items, replacement) {
/*
Create a map where the key is the id of replacement items.
This map will speed up the reconciling process in the
subsequent "map" stage
*/
const replacementMap = replacement.reduce((map, item) => {
map[ item.id ] = item
return map;
}, {})
/*
Map the items to a new array where items in the result array
are either clones of the orignals, or replaced by items of
"replacement" array where thier id matches the item being mapped
*/
return items.map(item => {
const use = replacementMap[ item.id ] || item
return { ...use }
})
}
const allItems = [
{
'id': 1,
'category_id': 1,
'text': 'old',
},
{
'id': 2,
'category_id': 1,
'text': 'old'
}
]
const newItems = [
{
'id': 1,
'category_id': 1,
'text': 'new',
'more_info': 'abcd'
},
{
'id': 2,
'category_id': 1,
'text': 'new',
'more_info': 'abcd'
}
]
console.log(replaceItemsOnId(allItems, newItems))