-3

Hi I would like to know how to check if the exact words contained in an array in Javascript are present in a string, like this

let filter = ["action", "romance"];
let genres = "action sci-fi romance horror";

this should be true

  • 2
    You can use [`every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) and [`includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes). But first you should read the [tour] _"Don't ask about... Questions you haven't tried to find an answer for (show your work!)"_ –  Jun 17 '21 at 10:47
  • You could use regex here – DecPK Jun 17 '21 at 10:53

3 Answers3

1

As stated by @jabaa, you can use every and includes:

const matches = filter.every((word) => genres.includes(word));
Leonardo da Silva
  • 1,285
  • 2
  • 10
  • 25
  • The OP was asking for exact _words_ so I'm assuming a substring match won't suffice since this will incorrectly match `comedy` to `tragicomedy` for example. – CherryDT Jun 17 '21 at 10:56
  • 1
    @CherryDT The question is _"how to check if the exact words contained in an array in Javascript are present in a string"_. It doesn't say that it has to be an exact word in the string. The array `['comedy']` and the string `'tragicomedy'` should return true. –  Jun 17 '21 at 10:58
  • Yes, and I would thereby say that the _exact word_ `abc` isn't present in the string `abcdef`, the _character sequence_ is. It would be in `abc def`, just like you won't consider the _number_ `42` to be present in the array `[193854, 1125016, 9912]` even though the byte `2A` (42) exists as part of `98 2A 11 00` (1125016) in memory, while it is in `[12, 42, 33]`... – CherryDT Jun 17 '21 at 11:04
  • 1
    @CherryDT Looks like the question is unclear and should be closed until this is clarified. –  Jun 17 '21 at 11:04
  • You are right, I can see now how one could also understand it the other way. – CherryDT Jun 17 '21 at 11:05
0

First, split the string into words by splitting at a word boundary:

const splitGenres = genres.split(/\b/)

This will also put things between words like punctuation and spaces into elements, but you probably don't need to care about them because you are searching for specific known values.

If you need to normalize case and always match to lower-case values, you can also convert the results to lower-case by appending .map(word => word.toLowerCase()) to the line above (mapping each element to its lower case representation). If your filter may also not be normalized yet, you can do the same to the filter array as well.

This whole method is under the assumption that the input string can have any format like a regular sentence. If this isn't the case and instead it's always a list separated by a single space, then you can also use .split(' ') instead.

Then, check whether all of the words in your filter array are also contained in the list of words which we have now extracted:

const allMatching = words.every(word => splitGenres.includes(word))

You then have a boolean in allMatching telling you whether your filter matches or not.

CherryDT
  • 25,571
  • 5
  • 49
  • 74
0

You could use Regex with map.

let filter1 = ["action", "romance"];
let filter2 = ["action", "romance", "not_present"];
let genres = "action sci-fi romance horror";

function isAllWordPresent(str, arr) {
  let count = 0;

  const result = arr.map((s) => {
    const regex = new RegExp(`\\b${s}\\b`);
    const result = regex.test(str);
    if (result) count++;
    return result;
  });
  return result.length === count;
}

console.log(isAllWordPresent(genres, filter1));
console.log(isAllWordPresent(genres, filter2));
DecPK
  • 24,537
  • 6
  • 26
  • 42
  • Why would you do that? Just because it's possible? –  Jun 17 '21 at 11:07
  • Since this is a filter I suppose it may have user input as its source. I would therefore suggest [escaping](https://stackoverflow.com/a/3561711/1871033) `s` before embedding it into a regular expression. – CherryDT Jun 17 '21 at 11:07
  • I just come up with this alternate solution so I thought it should be worth sharing... – DecPK Jun 17 '21 at 11:11