Home > front end >  How to remove an object from an array, if 2 item properties match from a second array?
How to remove an object from an array, if 2 item properties match from a second array?

Time:04-08

I have a messages[] array and a deletedMessages[] array. messages:

0: {userId: '7d014637', userName: 'me', text: "Let's play cards.", ts: '2022-04-07T22:42:34Z', date: Thu Apr 07 2022 18:42:34 GMT-0400 (GMT-04:00)}
1: {userId: '82f9cae5', userName: 'me', text: 'Lets go to the ball game.', ts: '2022-04-07T21:06:57Z', date: Thu Apr 07 2022 17:06:57 GMT-0400 (GMT-04:00)}
2: {userId: '9e2a4fdb', userName: 'me', text: 'Wreck it ralph', ts: '2022-04-07T22:36:22Z', date: Thu Apr 07 2022 18:36:22 GMT-0400 (GMT-04:00)}

deletedMessages:

6: {userId: '82f9cae5', userName: 'me', text: 'Lets go to the ball game.', ts: '2022-04-07T21:06:57Z', date: Thu Apr 07 2022 17:06:57 GMT-0400 (GMT-04:00)}
7: {userId: '9e2a4fdb', userName: 'me', text: 'Wreck it ralph', ts: '2022-04-07T22:36:22Z', date: Thu Apr 07 2022 18:36:22 GMT-0400 (GMT-04:00)}

object 1 and 2 in messages are the exact same as in deletedMessages objects 6 and 7.

I'd like to subtract these objects from the messages array so that in the end I have only the objects that don't match this criteria. So the end it would just be this. messages:

0: {userId: '7d014637', userName: 'me', text: "Let's play cards.", ts: '2022-04-07T22:42:34Z', date: Thu Apr 07 2022 18:42:34 GMT-0400 (GMT-04:00)}

And I would like to do this by finding matching properties. For example the userId value and the ts value.

I tried using filter like this but it didn't work, I believe because it's not filtering through the deletedMessages array properly.

let result = messages.filter(function( obj ) {
    return obj.userId !== deletedMessages.userId && obj.ts !== deletedMessages.ts;
});
console.log(result);

CodePudding user response:

You cannot use === on an array. Here is one variation.

Using Array.some

const arr1 = [{userId: '7d014637', userName: 'me', text: "Let's play cards.", ts: '2022-04-07T22:42:34Z', date: "Thu Apr 07 2022 18:42:34 GMT-0400 (GMT-04:00)"},
{userId: '82f9cae5', userName: 'me', text: 'Lets go to the ball game.', ts: '2022-04-07T21:06:57Z', date:" Thu Apr 07 2022 17:06:57 GMT-0400 (GMT-04:00)"},
 {userId: '9e2a4fdb', userName: 'me', text: 'Wreck it ralph', ts: '2022-04-07T22:36:22Z', date: "Thu Apr 07 2022 18:36:22 GMT-0400 (GMT-04:00)"}]

const deletedMessages = [{userId: '82f9cae5', userName: 'me', text: 'Lets go to the ball game.', ts: '2022-04-07T21:06:57Z', date: "Thu Apr 07 2022 17:06:57 GMT-0400 (GMT-04:00)"},
 {userId: '9e2a4fdb', userName: 'me', text: 'Wreck it ralph', ts: '2022-04-07T22:36:22Z', date: "Thu Apr 07 2022 18:36:22 GMT-0400 (GMT-04:00)"}]

const arr2 = arr1.filter(({ userId, ts }) => !deletedMessages.some(del => userId === del.userId && ts === del.ts))

console.log(arr2)

Or create an array of the concatenated values you are looking for.

const arr1 = [{userId: '7d014637', userName: 'me', text: "Let's play cards.", ts: '2022-04-07T22:42:34Z', date: "Thu Apr 07 2022 18:42:34 GMT-0400 (GMT-04:00)"},
{userId: '82f9cae5', userName: 'me', text: 'Lets go to the ball game.', ts: '2022-04-07T21:06:57Z', date:" Thu Apr 07 2022 17:06:57 GMT-0400 (GMT-04:00)"},
 {userId: '9e2a4fdb', userName: 'me', text: 'Wreck it ralph', ts: '2022-04-07T22:36:22Z', date: "Thu Apr 07 2022 18:36:22 GMT-0400 (GMT-04:00)"}]

const deletedMessages = [{userId: '82f9cae5', userName: 'me', text: 'Lets go to the ball game.', ts: '2022-04-07T21:06:57Z', date: "Thu Apr 07 2022 17:06:57 GMT-0400 (GMT-04:00)"},
 {userId: '9e2a4fdb', userName: 'me', text: 'Wreck it ralph', ts: '2022-04-07T22:36:22Z', date: "Thu Apr 07 2022 18:36:22 GMT-0400 (GMT-04:00)"}]
 
 const delArr = deletedMessages.map(({userId,ts}) => `${userId}${ts}`)
 console.log(delArr)
 const arr2 = arr1.filter(({userId,ts}) => !delArr.includes(`${userId}${ts}`))
 console.log(arr2)

CodePudding user response:

You need to extend the body of your filter function

let result = messages.filter(function( obj ) {
    // here
});

With method like this, you would need to go through every deletedMessage and if you find the same message there, you filter it (by returning false).

If you are interested about performance, this alghoritm is O(n^2), therefore if you got i.e. thousands of messages and deletedMessages it can become very CPU intensive.

If you want better performace, you would need to create i.e. Map first, put there all deletedMessages and then select from Map inside the function (instead of going through every deteledMessage)

  • Related