How to check if a string contains text from an array of substrings in JavaScript?
Asked Answered
O

24

325

Pretty straight forward. In javascript, I need to check if a string contains any substrings held in an array.

Orts answered 7/4, 2011 at 14:17 Comment(2)
Isn't there a map() function in the new HTML5-JavaScript-version? I remember having read something on that topic...Arbitrate
@Martin: Good point, not map so much as some. some would help, but you'd have to pass it a function.Clydesdale
C
472

There's nothing built-in that will do that for you, you'll have to write a function for it, although it can be just a callback to the some array method.

Two approaches for you:

  • Array some method
  • Regular expression

Array some

The array some method (added in ES5) makes this quite straightforward:

if (substrings.some(function(v) { return str.indexOf(v) >= 0; })) {
    // There's at least one
}

Even better with an arrow function and the newish includes method (both ES2015+):

if (substrings.some(v => str.includes(v))) {
    // There's at least one
}

Live Example:

const substrings = ["one", "two", "three"];
let str;

// Setup
console.log(`Substrings: ${substrings}`);

// Try it where we expect a match
str = "this has one";
if (substrings.some(v => str.includes(v))) {
    console.log(`Match using "${str}"`);
} else {
    console.log(`No match using "${str}"`);
}

// Try it where we DON'T expect a match
str = "this doesn't have any";
if (substrings.some(v => str.includes(v))) {
    console.log(`Match using "${str}"`);
} else {
    console.log(`No match using "${str}"`);
}

Regular expression

If you know the strings don't contain any of the characters that are special in regular expressions, then you can cheat a bit, like this:

if (new RegExp(substrings.join("|")).test(string)) {
    // At least one match
}

...which creates a regular expression that's a series of alternations for the substrings you're looking for (e.g., one|two) and tests to see if there are matches for any of them, but if any of the substrings contains any characters that are special in regexes (*, [, etc.), you'd have to escape them first and you're better off just doing the boring loop instead. For info about escaping them, see this question's answers.

Live Example:

const substrings = ["one", "two", "three"];
let str;

// Setup
console.log(`Substrings: ${substrings}`);

// Try it where we expect a match
str = "this has one";
if (new RegExp(substrings.join("|")).test(str)) {
    console.log(`Match using "${str}"`);
} else {
    console.log(`No match using "${str}"`);
}

// Try it where we DON'T expect a match
str = "this doesn't have any";
if (new RegExp(substrings.join("|")).test(str)) {
    console.log(`Match using "${str}"`);
} else {
    console.log(`No match using "${str}"`);
}
Clydesdale answered 7/4, 2011 at 14:21 Comment(5)
using .some how would you return the one that match?Macmacabre
@sreginogemoh - You wouldn't use some in that case, you'd use find, which returns the first element for which your callback returns a truthy value, or undefined if the callback never returns a truthy value.Clydesdale
yeah that's what I did, however I thought that some might handle that....Macmacabre
@sreginogemoh - Only if you do something like let x; if (array.some((v) => { if (/*... v matches condition ... */) { x = v; return true; } return false; })) { /*... use x` here ... */ }` but it's much simpler and more idiomatic to use find in that case. The only real reason for doing what I showed there is for when undefined is actually in the array and it's what you want to find. (With find you wouldn't know if you'd found it, or not found anything. With the above, you can tell the difference). Very rare case...Clydesdale
jsben.ch/NdFDq find/some & includes are (not by much) faster than the other solutions, other than RegExp which can be up to 2x slower.Odds
F
133

One line solution

substringsArray.some(substring=>yourBigString.includes(substring))

Returns true/false if substring exists/doesn't exist

Needs ES6 support

Fendley answered 21/9, 2017 at 6:53 Comment(3)
You kids...back when I was a kid we had to use these things called 'for' loops, and you had to use multiple lines and know whether your array was 1 or zero based, yeah...half the time you got it wrong and had to debug and look out for a little bugger called 'i'.Agist
@Agist The gold old dayss...Dissimulation
I like short answers.Blackpool
G
56
var yourstring = 'tasty food'; // the string to check against


var substrings = ['foo','bar'],
    length = substrings.length;
while(length--) {
   if (yourstring.indexOf(substrings[length])!=-1) {
       // one of the substrings is in yourstring
   }
}
Gouache answered 7/4, 2011 at 14:21 Comment(0)
M
30
function containsAny(str, substrings) {
    for (var i = 0; i != substrings.length; i++) {
       var substring = substrings[i];
       if (str.indexOf(substring) != - 1) {
         return substring;
       }
    }
    return null; 
}

var result = containsAny("defg", ["ab", "cd", "ef"]);
console.log("String was found in substring " + result);
Monaco answered 7/4, 2011 at 14:28 Comment(2)
Plus it returns the first occurence of the word in the string, which is very helpful. Not only a true/false.Mungovan
what is the es6 equivalent?Spruik
S
24

For people Googling,

The solid answer should be.

const substrings = ['connect', 'ready'];
const str = 'disconnect';
if (substrings.some(v => str === v)) {
   // Will only return when the `str` is included in the `substrings`
}
Spicule answered 13/6, 2015 at 9:52 Comment(2)
or shorter: if (substrings.some(v => v===str)) {Tubulate
Note that this is an answer to a slightly different question, which asks if a string contains text from an array of substrings. This code checks if a string is one of the substrings. Depends on what is meant by "contains" I suppose.Prorate
K
21

Here's what is (IMO) by far the best solution. It's a modern (ES6) solution that:

  • is efficient (one line!)
  • avoids for loops
  • unlike the some() function that's used in the other answers, this one doesn't just return a boolean (true/false)
  • instead, it either returns the substring (if it was found in the array), or returns undefined
  • goes a step further and allows you to choose whether or not you need partial substring matches (examples below)

Enjoy!



const arrayOfStrings = ['abc', 'def', 'xyz'];
const str = 'abc';
const found = arrayOfStrings.find(v => (str === v));

Here, found would be set to 'abc' in this case. This will work for exact string matches.

If instead you use:

const found = arrayOfStrings.find(v => str.includes(v));

Once again, found would be set to 'abc' in this case. This doesn't allow for partial matches, so if str was set to 'ab', found would be undefined.


And, if you want partial matches to work, simply flip it so you're doing:
const found = arrayOfStrings.find(v => v.includes(str));

instead. So if str was set to 'ab', found would be set to 'abc'.

Easy peasy!



Kosel answered 1/8, 2020 at 2:4 Comment(0)
V
8
var str = "texttexttext";
var arr = ["asd", "ghj", "xtte"];
for (var i = 0, len = arr.length; i < len; ++i) {
    if (str.indexOf(arr[i]) != -1) {
        // str contains arr[i]
    }
}

edit: If the order of the tests doesn't matter, you could use this (with only one loop variable):

var str = "texttexttext";
var arr = ["asd", "ghj", "xtte"];
for (var i = arr.length - 1; i >= 0; --i) {
    if (str.indexOf(arr[i]) != -1) {
        // str contains arr[i]
    }
}
Vittoria answered 7/4, 2011 at 14:23 Comment(2)
Your first example doesn't need the len variable, just check i < arr.length.Fran
the only answer that returns the matched array string. this should have been included in previous example for completeness sakeCady
S
5

const str = 'Does this string have one or more strings from the array below?';
const arr = ['one', 'two', 'three'];

const contains = arr.some(element => {
  if (str.includes(element)) {
    return true;
  }
  return false;
});

console.log(contains); // true
Suilmann answered 13/5, 2022 at 22:58 Comment(1)
Even shorter method: arr.some(element => str.includes(element) ? true : false)Suilmann
P
4
substringsArray.every(substring=>yourBigString.indexOf(substring) === -1)

For full support ;)

Pirzada answered 9/4, 2020 at 13:48 Comment(0)
R
4

For full support (additionally to @ricca 's verions).

wordsArray = ['hello', 'to', 'nice', 'day']
yourString = 'Hello. Today is a nice day'.toLowerCase()
result = wordsArray.every(w => yourString.includes(w))
console.log('result:', result)
Racoon answered 19/6, 2020 at 14:32 Comment(0)
M
3

If the array is not large, you could just loop and check the string against each substring individually using indexOf(). Alternatively you could construct a regular expression with substrings as alternatives, which may or may not be more efficient.

Meaningless answered 7/4, 2011 at 14:22 Comment(1)
Let's say we have a list of 100 substrings. Which way would be more efficient: RegExp or loop?Sportsman
P
3

Javascript function to search an array of tags or keywords using a search string or an array of search strings. (Uses ES5 some array method and ES6 arrow functions)

// returns true for 1 or more matches, where 'a' is an array and 'b' is a search string or an array of multiple search strings
function contains(a, b) {
    // array matches
    if (Array.isArray(b)) {
        return b.some(x => a.indexOf(x) > -1);
    }
    // string match
    return a.indexOf(b) > -1;
}

Example usage:

var a = ["a","b","c","d","e"];
var b = ["a","b"];
if ( contains(a, b) ) {
    // 1 or more matches found
}
Planck answered 27/10, 2016 at 23:9 Comment(0)
D
3

This is super late, but I just ran into this problem. In my own project I used the following to check if a string was in an array:

["a","b"].includes('a')     // true
["a","b"].includes('b')     // true
["a","b"].includes('c')     // false

This way you can take a predefined array and check if it contains a string:

var parameters = ['a','b']
parameters.includes('a')    // true
Disseminule answered 20/2, 2018 at 17:15 Comment(2)
this is the cleanest answer here. many thanks!Capitation
the question here is not string in an array but strings in an array in a sentenceCady
L
3

Best answer is here: This is case insensitive as well

    var specsFilter = [.....];
    var yourString = "......";

    //if found a match
    if (specsFilter.some((element) => { return new RegExp(element, "ig").test(yourString) })) {
        // do something
    }
Lysin answered 13/1, 2019 at 18:48 Comment(0)
H
2

Not that I'm suggesting that you go and extend/modify String's prototype, but this is what I've done:

String.prototype.includes()

String.prototype.includes = function (includes) {
    console.warn("String.prototype.includes() has been modified.");
    return function (searchString, position) {
        if (searchString instanceof Array) {
            for (var i = 0; i < searchString.length; i++) {
                if (includes.call(this, searchString[i], position)) {
                    return true;
                }
            }
            return false;
        } else {
            return includes.call(this, searchString, position);
        }
    }
}(String.prototype.includes);

console.log('"Hello, World!".includes("foo");',          "Hello, World!".includes("foo")           ); // false
console.log('"Hello, World!".includes(",");',            "Hello, World!".includes(",")             ); // true
console.log('"Hello, World!".includes(["foo", ","])',    "Hello, World!".includes(["foo", ","])    ); // true
console.log('"Hello, World!".includes(["foo", ","], 6)', "Hello, World!".includes(["foo", ","], 6) ); // false
Horthy answered 20/2, 2018 at 7:36 Comment(0)
T
2

building on T.J Crowder's answer

using escaped RegExp to test for "at least once" occurrence, of at least one of the substrings.

function buildSearch(substrings) {
  return new RegExp(
    substrings
    .map(function (s) {return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');})
    .join('{1,}|') + '{1,}'
  );
}


var pattern = buildSearch(['hello','world']);

console.log(pattern.test('hello there'));
console.log(pattern.test('what a wonderful world'));
console.log(pattern.test('my name is ...'));
Tripping answered 27/2, 2018 at 15:47 Comment(0)
B
2

Drawing from T.J. Crowder's solution, I created a prototype to deal with this problem:

Array.prototype.check = function (s) {
  return this.some((v) => {
    return s.indexOf(v) >= 0;
  });
};
Backspace answered 18/8, 2018 at 23:10 Comment(0)
S
1

Using underscore.js or lodash.js, you can do the following on an array of strings:

var contacts = ['Billy Bob', 'John', 'Bill', 'Sarah'];

var filters = ['Bill', 'Sarah'];

contacts = _.filter(contacts, function(contact) {
    return _.every(filters, function(filter) { return (contact.indexOf(filter) === -1); });
});

// ['John']

And on a single string:

var contact = 'Billy';
var filters = ['Bill', 'Sarah'];

_.every(filters, function(filter) { return (contact.indexOf(filter) >= 0); });

// true
Slant answered 8/11, 2017 at 0:39 Comment(0)
O
1

If you're working with a long list of substrings consisting of full "words" separated by spaces or any other common character, you can be a little clever in your search.

First divide your string into groups of X, then X+1, then X+2, ..., up to Y. X and Y should be the number of words in your substring with the fewest and most words respectively. For example if X is 1 and Y is 4, "Alpha Beta Gamma Delta" becomes:

"Alpha" "Beta" "Gamma" "Delta"

"Alpha Beta" "Beta Gamma" "Gamma Delta"

"Alpha Beta Gamma" "Beta Gamma Delta"

"Alpha Beta Gamma Delta"

If X would be 2 and Y be 3, then you'd omit the first and last row.

Now you can search on this list quickly if you insert it into a Set (or a Map), much faster than by string comparison.

The downside is that you can't search for substrings like "ta Gamm". Of course you could allow for that by splitting by character instead of by word, but then you'd often need to build a massive Set and the time/memory spent doing so outweighs the benefits.

Ordovician answered 15/5, 2019 at 6:40 Comment(0)
S
1
convert_to_array = function (sentence) {
     return sentence.trim().split(" ");
};

let ages = convert_to_array ("I'm a programmer in javascript writing script");

function confirmEnding(string) {
let target = "ipt";
    return  (string.substr(-target.length) === target) ? true : false;
}

function mySearchResult() {
return ages.filter(confirmEnding);
}

mySearchResult();

you could check like this and return an array of the matched words using filter

Slake answered 7/9, 2020 at 22:7 Comment(0)
M
1

I had a problem like this. I had a URL, I wanted to check if the link ends in an image format or other file format, having an array of images format. Here is what I did:

const imagesFormat = ['.jpg','.png','.svg']
const link = "https://res.cloudinary.com/***/content/file_padnar.pdf"
const isIncludes = imagesFormat.some(format => link.includes(format))
    
// false
Medullated answered 3/9, 2021 at 8:1 Comment(0)
H
0

You can check like this:

<!DOCTYPE html>
<html>
   <head>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
      <script>
         $(document).ready(function(){
         var list = ["bad", "words", "include"] 
         var sentence = $("#comments_text").val()

         $.each(list, function( index, value ) {
           if (sentence.indexOf(value) > -1) {
                console.log(value)
            }
         });
         });
      </script>
   </head>
   <body>
      <input id="comments_text" value="This is a bad, with include test"> 
   </body>
</html>
Hotbox answered 16/12, 2019 at 11:0 Comment(0)
D
-1
let obj = [{name : 'amit'},{name : 'arti'},{name : 'sumit'}];
let input = 'it';

Use filter :

obj.filter((n)=> n.name.trim().toLowerCase().includes(input.trim().toLowerCase()))
Donatus answered 17/2, 2020 at 11:28 Comment(2)
please visit and check how to answer a question.Alcaraz
@YunusTemurlenk thnxDonatus
G
-1

var str = "A for apple"
var subString = ["apple"]

console.log(str.includes(subString))
Glossary answered 23/8, 2021 at 15:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.