Reputation: 65
I have two arrays, i want to push some items from arr1 to arr2 preventing duplicates because i've already added some items to arr2 that are also in arr1. i am doing this in react js
arr1.forEach(q1 => {
arr2.forEach(q2 => {
if (q1.lessonId !== q2.lessonId) {
if (q2.obtainedMarks >= q2.passingMarks) {
User.findByIdAndUpdate(req.body.userId, { $push: { arr1: { $each:
[q2._id] } } }, (err, doc) => {
})
}
}
})
});
Upvotes: 2
Views: 1074
Reputation: 39270
You create a Set of arr1 lessonId's and then use array filter to filter out everything from arr2 that is already in arr1 and then filter again to get only passing items:
//get all lessonId for arr1 in a Set
const arr1Ids = new Set(arr1.map(x=>x.lessonId));
//get items of arr2 that are not already in arr1
const passingArr2NotInArr1 = arr2
.filter(
//take out everything that is already in arr1
item => !arr1Ids.has(item.lessonId)
)
.filter(
//only when it passed
item => item.obtainedMarks >= item.passingMarks
);
Upvotes: 1
Reputation: 50797
I have no idea what your User.findByIdAndUpdate
or $push
do, but if you just want to combine the non-duplicated items from the second array in the first, only when the marks comparison works, then you could write something like this:
const addWithoutDups = (arr1, arr2, ids = new Set (arr1 .map (x => x .lessonId))) =>
[
...arr1,
...arr2.filter((x) => !ids .has (x .lessonId) && x .obtainedMarks > x .passingMarks)
]
const arr1 = [
{lessonId: 1, more: 'here...'},
{lessonId: 2, more: 'here...'},
{lessonId: 3, more: 'here...'},
{lessonId: 4, more: 'here...'}
]
const arr2 = [
{lessonId: 2, obtainedMarks: 10, passingMarks: 7},
{lessonId: 3, obtainedMarks: 5, passingMarks: 12},
{lessonId: 5, obtainedMarks: 10, passingMarks: 6},
{lessonId: 7, obtainedMarks: 13, passingMarks: 8},
{lessonId: 11, obtainedMarks: 10, passingMarks: 15},
]
console .log (
addWithoutDups (arr1, arr2)
)
Note that ids 2
and 3
are rejected as duplicates, id 11
fails the qualification, but ids 5
and 7
are added properly.
Also note that this returns a new array with your data; it does not mutate the original. (I won't take part in such obscenities!)
Upvotes: 3
Reputation: 131
If items are same -> they have same reference, use Set
as the answer of Sokushinbutsu
If not, use Array.prototype.some()
const arr1Difference = arr1.filter((arr1Item) => {
const isSomeInArr2 = arr2.some((arr2Item) => {
return arr1Item.lessonId === arr2Item.lessonId
// return arr1Item === arr2Item (In the case that items are same -> they have same reference)
})
return !isSomeInArr2
})
const arr2AddToArr1Difference = [...arr2, ...arr1Difference ]
Upvotes: 1
Reputation: 83
You can use a set instead of an array. They have the built in feature of preventing duplicate entries. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
Upvotes: 3