Reputation: 2064
I'm able to successfully return an array based on if it contains a tag that equals === 'Featured'. Here is the code:
getFeatured() {
return blogPosts.filter((item) => (
item.tags.some((value) => value === 'Featured')
))
}
This filters each blog post, then I use .some() on the array of tags within the post.
I need to now create a function that returns an array of posts that don't contain the word "Featured".
Here is the function so far:
renderRegular() {
const regularPost = blogPosts.filter((item) => (
item.tags.find((value) => value !== 'Featured' )
))
console.log(regularPost)
}
Upvotes: 4
Views: 2152
Reputation: 21161
You need to use Array.prototype.every()
instead of Array.prototype.find()
, which will return true
if all the elements satisfy the predicate. In this case, if all the tags (every tag) are not equal to 'Featured'
or, put in a different way, if none of the tags is equal to 'Featured'
(see also @Barmar's answer):
const posts = [{
title: 'Post 1',
tags: ['Featured'],
}, {
title: 'Post 2',
tags: ['Foo', 'Featured'],
}, {
title: 'Post 3',
tags: ['Bar'],
}];
const regularPost = posts.filter(item =>
item.tags.every(value => value !== 'Featured'));
console.log(regularPost);
The advantage of this is that you can also check conditions other than equal or not equal easily:
const posts = [{
title: 'Post 1',
tags: ['Featured'],
}, {
title: 'Post 2',
tags: ['Foo', 'FEATURED POSTS'],
}, {
title: 'Post 3',
tags: ['Bar'],
}];
const regularPost = posts.filter(item =>
item.tags.every(value => !value.match(/featured/gi)));
console.log(regularPost);
But if you are only doing an equality comparison, Array.prototype.indexOf()
or Array.prototype.includes()
might be better options:
const posts = [{
title: 'Post 1',
tags: ['Featured'],
}, {
title: 'Post 2',
tags: ['Foo', 'Featured'],
}, {
title: 'Post 3',
tags: ['Bar'],
}];
// const regularPost = posts.filter(item =>
// item.tags.indexOf('Featured') === -1);
const regularPost = posts.filter(item =>
!item.tags.includes('Featured'));
console.log(regularPost);
Upvotes: 2
Reputation: 85545
You may assign the item:
renderRegular() {
const regularPost = blogPosts.filter((item) =>
// assign item so the filter will return item matched condition with the find
item = item.tags.find((value) => value !== 'Featured'
))
}
Upvotes: 0
Reputation: 781068
Simply negating the test is not the way to do this. If the tags are Tag1, Featured, Tag2
, your test will succeed because "Tag1" != "Featured"
.
Instead, you need to negate the result of some()
rather than the test inside it.
renderRegular() {
return blogPosts.filter((item) => (
!item.tags.some((value) => value === 'Featured')
))
}
Or you can apply de Morgan's Laws. The opposite of "some X == Y" is "every X != Y":
renderRegular() {
return blogPosts.filter((item) => (
item.tags.every((value) => value !== 'Featured')
))
}
Upvotes: 2
Reputation: 6233
find
will return first element that matches your condition, as it will return a element i.e. a string which will evaluate to true always. Use indexOf
to search for presence of string.
renderRegular() {
const regularPost = blogPosts.filter((item) => (
item.tags.indexOf('Featured') === -1
))
console.log(regularPost)
}
Upvotes: 0