Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ES6 .filter() that will return an array of objects WITHOUT certain strings

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)

  }
like image 514
Dileet Avatar asked Nov 01 '25 16:11

Dileet


2 Answers

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);
like image 131
Danziger Avatar answered Nov 04 '25 08:11

Danziger


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')
    ))
  }
like image 42
Barmar Avatar answered Nov 04 '25 06:11

Barmar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!