Multiple conditions for result filter

Viewed 66

I have an array of objects that I am filtering through based on a query. If the query matches a title inside the array of objects I return it.

  const arr = [{ title: 'Xbox one controller' }];

  const filterResults = arr.filter((item) =>
    item.title.toLowerCase().includes(req.query.q.toLowerCase())
  );

  res.send(filterResults);

These words if I just search on a word like "xbox", however, if I search "xbox controller" it returns nothing.

I was thinking of splitting req.query like this: const reqy = req.query.q.split(' ') and using those as keywords although I don't really know where to start. Another potential problem with my "solution" is that if a query looks like "Controller for Xbox One" will the result even show up?

My problem is making the filter function accept multiple "keywords" derived from the user query.

3 Answers

You can use split & some (or every if you want all words are matched) to achieve your expected result.

  • split: Split a string into an array of substrings:
  • some: The some() method tests whether at least one element in the array passes the test implemented by the provided function
  • every: The every() method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value.
    const arr = [{ title: 'Xbox one controller' }];
    
    const query = 'xbox controller2';
    const splitedQuery = query.split(' ');
    
    const filterResults = arr.filter(item => {
      let splitedTitle = item.title.split(' ');
      return splitedTitle.some(r => splitedQuery.some(q => r.toLowerCase() == q.toLowerCase()));
    });
    
    console.log(filterResults);

There are many ways to do it. Here is one example for you.

const arr = [{ title: 'Xbox one controller' }];
const req = { query: { q: 'Xbox controller' } }

  const filterResults = arr.filter((item) => {
   const queries = req.query.q.split(' ');
   return queries.find((text) => item.title.toLowerCase().includes(text.toLowerCase()))
  });
  
  console.log(filterResults)

One possible solution is to check whether every word in your search term occurs in the title. You can call the split method on your searchTerm to get an array of words in the search term. Then call the every method to verify whether all of the words in the search term appear in the title. As before, you can still use the filter method to remove those entries whose titles do not contain all of the words in the search term.

const searchTerm = 'xbox controller';

const arr = [{ title: 'Xbox one controller' }];

const filterResults = arr.filter(({ title }) =>
  searchTerm
    .toLowerCase()
    .split(' ')
    .every(keyword => title.toLowerCase().includes(keyword))
);
Related