Reputation: 147
I am having issues trying to filter an array of message objects. I do not want to include the objects with "_id" value "receiver" or "blockedUsers".
Array of message objects:
[
{"_id":"receiver"},
{"_id":"blockedUsers"},
{"_id": MjIzx3XA1mpcuzgDVZj","createdAt":1631349363111,"text":"Ok","user":{"name":"Nikki","_id":"M6fBsPludfYVjJXKYvwgxHRacYw1"}},
{"_id":" MjG3hFAgcNweJWh9SF7","createdAt":1631300277391,"text":"Again","user":{"name":"Chris","_id":"tFhmw5oQoPhk8nF2sx5rE5BFqw93"}
}
]
The following doesn't seem to work
this.state.messages.filter(msg => !msg._id.includes("receiver") || !msg._id.includes("blockedUsers")).
The original array is returned.
But if I use this
this.state.messages.filter(msg => msg._id.includes("receiver") || msg._id.includes("blockedUsers"))
it returns:
[{"_id":"receiver"},{"_id":"blockedUsers"}]
Can you please assist?
Upvotes: 0
Views: 919
Reputation: 19070
You can combine Array.prototype.filter() with Array.prototype.includes():
const arr = [{ _id: 'receiver' },{ _id: 'blockedUsers' },{ _id: 'MjIzx3XA1mpcuzgDVZj', createdAt: 1631349363111, text: 'Ok', user: { name: 'Nikki' } },{ _id: 'M6fBsPludfYVjJXKYvwgxHRacYw1' },{ _id: ' MjG3hFAgcNweJWh9SF7', createdAt: 1631300277391, text: 'Again', user: { name: 'Chris', _id: 'tFhmw5oQoPhk8nF2sx5rE5BFqw93' }}]
const result = arr.filter(({ _id }) => !['receiver', 'blockedUsers'].includes(_id))
console.log(result)
Upvotes: 0
Reputation: 28137
The filter condition is wrong, it will always return true in your case.
Array.filter() callback should return true
for the items you want to keep.
You have to use AND &&
instead of OR ||
.
this.state.messages.filter(msg =>
!msg._id.includes("receiver") && !msg._id.includes("blockedUsers")
)
Why it initially returned true? Because when the id is "receiver", it doesn't include "blockedUsers" and the other way around. You want to keep the element if it doesn't include "receiver" AND it also doesn't include "blockedUsers".
Here is a truth table to make it more clear, it should be true
for the items you want to keep.
!includes("receiver") | !includes("blockedUsers") | OR | AND |
---|---|---|---|
false | false | false ✅ | false ✅(skip item, it includes both strings) |
false | true | true ❌ | false ✅(skip item, it includes "blockedUsers") |
true | false | true ❌ | false ✅(skip item, it includes "receiver") |
true | true | true ❌ | true ✅(this is the only case where you want to keep the item, when it doesn't include either string) |
Upvotes: 2