How to Use JavaScript to Find Matches in Strings and Arrays

Determining if a String or Array contains a sub string or set of characters using JavaScript is a common task. Most developers expect a native JavaScript contains method since most languages use contains.

As with many things JavaScript is slightly different.

With ES6 JavaScript added the includes method natively to both the Array and String natives. The method returns true or false to indicate if the sub-string or element exists. While true or false may provide the answer you need, regular expressions can check if a sub-string exists with a more detailed answer.

Until recently developers would need to create their own method using either indexOf or a regular expression.

That changed in more recent versions of ECMAScript with the addition of the JavaScript includes method.

`JavaScript includes()

ECAMScript 6 added the includes method to both the String and Array objects natively. This method returns either true or false if the target string is contained within the source string or array.



let sample = "The human body is a remarkably adaptable machine. Even if years and years of neglect have allowed pound after pound of fat to fill out your frame, you can rid yourself of that lard at a much faster rate than you brought it on board. In that sense, time is your side!";

sample.includes("year");
//returns   true

sample.includes("foo");
//returns   false

let arr = ["one", "two", "three", "four", "five"];

arr.includes("two");
//returns   true

arr.includes("foo");
//returns   false

There is an optional fromIndex parameter you can add to indicate the first position the includes method should search.

sample.includes("year", 100);
//returns   false

If a negative fromIndex value is supplied the source string or array is searched from position 0.

For arrays, the search value must match an element, You can’t match a substring of an element.

JavaScript Includes Method Compatibility

The good news is browsers have good coverage of the JavaScript includes method. The only browser you need to worry about is Internet Explorer and old and deprecated NodeJs instances. You may also find a few legacy Android browsers hanging around.

Array.includes support:

Chrome Edge FireFox Safari Samsung
47 14 32 9 Yes

Even though Chrome supports the includes method you should know the Google spider uses Chrome 42 to evaluate pages. This means you need to have a polyfil available if your code uses this method.

String.includes support:

Chrome Edge FireFox Safari Samsung
41 Yes 40 9 Yes

JavaScript String Contains Polyfil

There are always polyfils available for modern functionality, well at least most of the time. The JavaScript string includes method is no different.

Part of the ECMAScript project includes the official polyfil. You can add it to a script to dynamically load if needed.

This is the official JavaScript string includes polyfil.

// https://tc39.github.io/ecma262/#sec-array.prototype.includes
if (!Array.prototype.includes) {
  Object.defineProperty(Array.prototype, 'includes', {
    value: function(searchElement, fromIndex) {

      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }

      // 1. Let O be ? ToObject(this value).
      var o = Object(this);

      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;

      // 3. If len is 0, return false.
      if (len === 0) {
        return false;
      }

      // 4. Let n be ? ToInteger(fromIndex).
      //    (If fromIndex is undefined, this step produces the value 0.)
      var n = fromIndex | 0;

      // 5. If n ≥ 0, then
      //  a. Let k be n.
      // 6. Else n < 0,
      //  a. Let k be len + n.
      //  b. If k < 0, let k be 0.
      var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

      function sameValueZero(x, y) {
        return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
      }

      // 7. Repeat, while k < len
      while (k < len) {
        // a. Let elementK be the result of ? Get(O, ! ToString(k)).
        // b. If SameValueZero(searchElement, elementK) is true, return true.
        if (sameValueZero(o[k], searchElement)) {
          return true;
        }
        // c. Increase k by 1. 
        k++;
      }

      // 8. Return false
      return false;
    }
  });
}

The string polyfil is simpler:

if (!String.prototype.includes) {
  String.prototype.includes = function(search, start) {
    'use strict';
    if (typeof start !== 'number') {
      start = 0;
    }
    
    if (start + search.length > this.length) {
      return false;
    } else {
      return this.indexOf(search, start) !== -1;
    }
  };
}

Before you go an include the polyfil by default you should feature detect to determine if the script needs to be loaded.

The key to detecting support is the first line of the polyfil:

if (!Array.prototype.includes) {
    //load includes polyfil
}

Finding a Sub-String Using indexOf

The first old school way to identify if a string or array contains a string is using the indexOf method. If the string or array contains the target string the method returns the first character index (string) or item index (Array) of the match.

If there is no match found indexOf returns -1. This is because arrays are zero indexed in JavaScript, so -1 means the value does not exist.

function contains(src, test){

    return src.indexOf(test) !== -1;    
    
}

The method returns true if the target string exists and false if it doesn’t.

Using Regex to Determine if a Sub-String Exist

The indexOf method is pretty basic, but not the most flexible technique. I prefer using regular expressions because you can craft all sorts of patterns.

The main advantage regular expressions have is they are not limited to a single string. Regular expressions utilize a pattern, which means you can match multiple items in a string or array. This works great for parsing data, a common business scenario.

There are also multiple native regex methods to test for the presence of a string pattern.

The search method works like the indexOf method. It returns the first position a match is found. If no match is found -1 is returned.

var src = "foo",
    expr = /oo/;
    
src.search(expr);

The next method is match. This works differently than the other methods because it returns an object representing the match.

sample.match(/years/)

//returns
{
    0: "years",
    groups : undefined,
    index : 58,
    input : "The human body is a remarkably adaptable machine. Even if years and years of neglect have allowed pound after pound of fat to fill out your frame, you can rid yourself of that lard at a much faster rate than you brought it on board. In that sense, time is your side!",
    length : 1
}

The match object includes the index where the match was found. It also includes the original test string or array.

The interesting thing is when you modify the regular expression with the global modifier (g) the method returns an array of the matched values, not the full match object.

sample.match(/years/g)

//returns
["years","years"]

The downside to using match is it only works on strings, not arrays.

The last regular expression method is test. This works very differently than the other methods.

Here you call test from the regular expression pattern and supply the source string. If there is a match in the source string the method returns true. If there is no match it returns false.

/year/.test(sample)

//returns true

/foo/.test(sample)

//returns false

The downside to this method is lack of detail. It does provide true or false about a match, but you do not know where the match was found or how many were found. It is a simple test.

Summary

You can safely use the JavaScript includes method for both Arrays and Strings today. But like most modern APIs you should do feature detection in the browser to determine if a polyfil should be loaded. For the most part this won’t be an issue unless a user happens to be using Internet Explorer. And since IE should only be limited to use with legacy web applications in enterprises the chances of encountering a browser not supporting includes is slim.

The includes method only returns true or false is the criteria exists in the array or string. If you need to know the match index or indexes you should revert to either indexOf or a more advanced regular expression.

Thank you for reading! Share this Article with Your Friends!

#JavaScript #Arrays

How to Use JavaScript to Find Matches in Strings and Arrays
1 Likes18.45 GEEK