Intersect between two arrays of objects and keep only matched element and delete the non-matching element based on key of object


Intersect between two arrays of objects and keep only matched element and delete the non-matching element based on key of object



I have two arrays of objects and I need to intersect between the arrays to find out the common one and delete it from the first array which does not have the same item based on one of the keys.



Note that I want to mutate the first array itself.



Here is my code sample and what I tried with .map but did not get the expected result.


.map




(() => {
const first = Array.from({ length: 5 }, (_, i) => ({
id: `in-${i}`,
name: "one",
age: `${i * 5}`
}));

const second = Array.from({ length: 3 }, (_, i) => ({
id: `in-${i}`,
name: "two"
}));
console.log({ first });
console.log({ second });
const sid = second.map(s => s.id);

first.map((f, i) => {
if (sid.includes(f.id)) {
console.log("✔️ included");
} else {
console.log("👎🏻 not included");
first.splice(i, 1);
}
});
console.log("...now...");
console.log({ first });
console.log({ second });
})();



This does not delete the last array element of first array.



Expected output:


[ { id: 'in-0', name: 'one', age: '0' },
{ id: 'in-1', name: 'one', age: '5' },
{ id: 'in-2', name: 'one', age: '10' }
] }



Actual output:


[ { id: 'in-0', name: 'one', age: '0' },
{ id: 'in-1', name: 'one', age: '5' },
{ id: 'in-2', name: 'one', age: '10' },
{ id: 'in-4', name: 'one', age: '20' } ] }



What mistake am I doing here? Kindly help.



Also, suggest any other shorter and simplified ways. I think I can use .reduce / forEach here but I do not know how.


.reduce





I have added the code snippet. do I need to add input again?
– pro.mean
Jun 29 at 17:03





no sorry I just missed it
– Pointy
Jun 29 at 17:06





The issue probably has something to do with the fact that you're changing the array in the middle of the .map() call.
– Pointy
Jun 29 at 17:07


.map()





yes, my guess is the same but how to achieve the expected output? I do not want to assign the result into new array neither can do first = first.map(..) so I have to change the first array itself
– pro.mean
Jun 29 at 17:09


first = first.map(..)




2 Answers
2



When you get past element 2, your callback will remove element 3. That was index 4 in the array, so the next iteration removes element 5. Element 4 is skipped because the innards of .map() don't know that you're mutating the array.


.map()



I personally would just use a simple for loop if you don't want to make a new array:


for


for (let i = first.length; --i >= 0; ) {
if (!sid.includes(first[i].id))
first.splice(i, 1);
}



If you loop from the end towards the start, splicing elements out doesn't mess things up.





Thanks. can I use for..in or for..of loop here
– pro.mean
Jun 29 at 17:19


for..in


for..of



you can use .filter()


.filter()


const result = first.filter(f => sid.includes(f.id) );



if you want to mutate the first array, don't use const, replace it with a let and overwrite it like :


first


const


let


first = first.filter(f => sid.includes(f.id));




(() => {
// replace const with let
let first = Array.from({
length: 5
}, (_, i) => ({
id: `in-${i}`,
name: "one",
age: `${i * 5}`
}));

const second = Array.from({
length: 3
}, (_, i) => ({
id: `in-${i}`,
name: "two"
}));

const sid = second.map(s => s.id);

// use .filter and overwrite the first array
first = first.filter(f => sid.includes(f.id));

console.log(first);

})();





I agree that this would be the right thing to do, but the OP apparently wants to mutate the first array.
– Pointy
Jun 29 at 17:10





sorry but I could not assign first = first.filter in this specific problem.
– pro.mean
Jun 29 at 17:11


first = first.filter





@pro.mean i see, in that case i would've suggest a simple for loop and splice but @Pointy beat me to it.
– Taki
Jun 29 at 17:15


for


splice






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Export result set on Dbeaver to CSV

Opening a url is failing in Swift