Reputation: 3060
I have two arrays of objects
let current = [
{
categoryId: 18,
id: 'fire_18',
test: 'test'
}, {
oldItem: "items that dont exist in new array should be deleted"
}
]
let new_data = [
{
id: 'fire_18',
categoryId: 18,
test1: 'test1',
}, {
newItem: "new items should be added to final"
}
]
I need to merge those so the result is not missing data from current
array. The desired result looks like this
[
{
id: 'fire_18',
categoryId: 18,
test1: 'test1',
test: 'test'
}, {
newItem: "new items should be added to final"
}
]
Here is my attempt
let current = [
{
categoryId: 18,
id: 'fire_18',
test: 'test'
}, {
oldItem: "items that dont exist in new array should be deleted"
}
]
let new_data = [
{
id: 'fire_18',
categoryId: 18,
test1: 'test1',
}, {
newItem: "new items should be added to final"
}
]
console.log(' === Current ==>', current);
console.log(' === New ==>', new_data);
new_data.map(newItem => {
let currentMatch;
try { // incase new item newItem.categoryId wont exist
currentMatch = current.find(c => c.categoryId == newItem.categoryId) || {};
} catch (error) { // in that case, no need to merge
currentMatch = {};
}
return Object.assign(currentMatch, newItem);
});
console.log(' === Merged ==>', new_data);
the main thing wrong still is test
key from the current
arr is missing after merge.
Can anyone modify the pen to not delete keys from the current
arr?
Upvotes: 0
Views: 88
Reputation: 23858
Note that Array.map
method returns a new array. You are not logging this merged new array - but one of your old arrays.
Also, you don't need try catch
here. You may also note that if the categoryId
is undefined, the objects will still match. So, you need a check for that.
let current = [
{
categoryId: 18,
id: 'fire_18',
test: 'test'
}, {
oldItem: "items that dont exist in new array should be deleted"
}
]
let new_data = [
{
id: 'fire_18',
categoryId: 18,
test1: 'test1',
}, {
newItem: "new items should be added to final"
}
]
newArray = new_data.map(newItem => {
let currentMatch;
currentMatch = current.find(c => c.categoryId === newItem.categoryId && newItem.categoryId) || {};
return Object.assign(currentMatch, newItem);
});
console.log(' === Merged ==>', newArray);
Upvotes: 1
Reputation: 4148
I found this. On your code it goes like that:
let current = [
{
categoryId: 18,
id: 'fire_18',
test: 'test'
}, {
oldItem: "items that dont exist in new array should be deleted"
}
]
let new_data = [
{
id: 'fire_18',
categoryId: 18,
test1: 'test1',
}, {
newItem: "new items should be added to final"
}
]
function merge(a, b, prop){
var reduced = a.filter(function(aitem){
return ! b.find(function(bitem){
return aitem[prop] === bitem[prop];
});
});
return reduced.concat(b);
}
console.log(merge(current, new_data, "id") );
Upvotes: 0
Reputation: 2944
You can use es6 spread operator to meet your requirement
var current = [{
categoryId: 18,
id: 'fire_18',
name: 'Servers',
slugName: 'fire_18',
test: 'test'
}]
var new_data = [{
id: 'fire_18',
categoryId: 18,
name: 'Servers',
slugName: 'fire_18'
}]
const results = new_data.map(item => {
let newItem = { ...item };
const currentMatchItem = current.find(c => c.categoryId == newItem.categoryId);
if (currentMatchItem) {
newItem = { ...currentMatchItem, ...newItem };
}
return newItem;
});
console.log(results);
Upvotes: 0
Reputation: 27285
Like this? I'm not sure what you're expecting to happen with the newItem
and oldItem
entries.
let current = [{
categoryId: 18,
id: 'fire_18',
test: 'test'
}]
let new_data = [{
id: 'fire_18',
categoryId: 18,
test1: 'test1',
}]
const result = Object.values([...current, ...new_data].reduce((acc, {
categoryId,
...other
}) => ({
...acc,
[categoryId]: {
categoryId,
...other
}
}), {}));
console.log(result);
Upvotes: 0
Reputation: 1403
You can use lodash for this.
finalArr = _(_.flatten([current, new_data]))
.groupBy('id')
.map(_.spread(_.assign))
.value();
Upvotes: 0