Checking whether or not a string contains another string, or just a single character. It’s a been a pretty unavoidable sanity check in my programming career. It’s not quite a problem for the ages, but it comes up regularly and can be approached a few different ways.

ES5 and prior

indexOf

Ahhhhh indexOf. It can tell you if an array contains a value or whether or not a string contains another string. You won’t receive a boolean from this method, since it it used to detect the position of the first instance or -1 when the value isn’t found. Fortunately we can just cast the value as a boolean:

const haystack  = 'This is my amazing string';
const needle    = 'amazing';
const hasNeedle = !!(haystack.indexOf(needle) > -1);

RegExp

Good ol’ RegExp. Often times frowned upon due to speed implications. With modern JavaScript, RegExp is quite performant and comes with a handful of methods that could leveraged to check if a string contains another string. The most basic of these methods is RegExp.test() which simply tests whether or not a string passes the regular expression:

const haystack  = 'This is my amazing string';
const needle    = new RegExp('amazing'); // or simply /amazing/
const hasNeedle = needle.test(haystack);

Using regular expressions has the added bonus of being able to do case insensitive searches:

const haystack  = 'This is my amazing string';
const needle    = new RegExp('amazing', 'i'); // or simply /amazing/i
const hasNeedle = needle.test(haystack);

ES6

Granted, all of the aforementioned methods still work here in the modern world, but if you are able to leverage ES6, why wouldn’t you?

includes

Similar to indexOf, includes is one of those methods that can work with both arrays and strings (yes, strings are technically arrays). The advantage to using includes is that it returns a boolean value meaning that it’s been designed more for our use case of finding a string in another string:

const haystack  = 'This is my amazing string';
const needle    = 'amazing'
const hasNeedle = haystack.includes(needle);

But sadly, includes doesn’t support case insensitive searches, so if that’s a requirement ES6 has to take the back burner.