JavaScript indexOf() Method
This tutorial explains the indexOf() method, part of the JavaScript String object. The indexOf() method allows you to retrieve the position index of the first instance of a substring in a given string. It offers a user-friendly but limited functionality, similar to JavaScript's pattern-matching regular expressions (the RegExp object, covered in later tutorials).
The indexOf() method is case-sensitive: searching for a given lowercase letter will not produce a match if the letter only appears in uppercase.
Related string method:
Unlike indexOf(), the lastIndexOf() method matches the last instance of a substring in another string.
Using the indexOf() Method
The syntax of the indexOf() method is as follows: you append it with the dot operator after a string variable, and pass as argument the string you want to find in the other string variable. (indexOf() is case-sensitive, but we will show you how to work around what can in some cases be a limitation.)
// Find needle in haystack (two pre-declared strings)
haystack.indexOf(needle);
Both searched-for string and searched-in string can be either a declared variable or an anonymous quoted string (a "literal"). We demonstrate below searching for an anonymous string match in a declared string variable:
var carter = new String("I learn JavaScript.");
// Use indexOf() to find position index of first space character
alert( carter.indexOf(" ") );
The JavaScript alert displayed by our script returns 1 (which is the position index of the second character, since the position index starts at zero).
The indexOf() Method and Failed Matches
Upon finding a successful match, the indexOf() method will return zero or a positive integer, indicating the position index of the first match found.
What happens if no match is found?
var carter = new String("I learn JavaScript.");
// Note the lowercase "javascript" we pass to indexOf()
alert( carter.indexOf("javascript") );
Since "javascript" (lowercase) does not appear in our string variable, the indexOf() method could not find a match — and therefore, could not return a position index value. In such cases, indexOf() returns the value -1:
Making indexOf() case-insensitive
Remember: the indexOf() method is case-sensitive: a lowercase letter does not have the same value as its uppercase equivalent. The easiest way around this limitation is to convert the searched-in string, using the toLowerCase() method or the toUpperCase() method, or convert both strings, as shown in this script:
var myFav = "javascript";
var theList = "VB.NET, C#, PHP, Python, JavaScript, and Ruby";
// Check for matches with the plain vanilla indexOf() method:
alert( theList.indexOf( myFav ) );
// Now check for matches in lower-cased strings:
alert( theList.toLowerCase().indexOf( myFav.toLowerCase() ) );
Explanations: in the first alert()
, JavaScript returned "-1" - in other words, indexOf() did not find a match: this is simply because "JavaScript" is in lowercase in the first string, and properly capitalized in the second. To perform case-insensitive searches with indexOf(), you can make both strings either uppercase or lowercase. This means that, as in the second alert(), JavaScript will only check for the occurrence of the string you are looking for, capitalization ignored.
In the second alert(), JavaScript thus returned "25", the character position index at which the term "javascript"
appears in the second string.
Using indexOf() character positions as conditional checks
Knowing that zero or a negative number is also interpreted as "false" by the JavaScript interpreter, you can use a "-1" as a condition check: this makes your code slightly harder to understand, but very clean:
if( catalog.indexOf(bookTitle)+1 ) {
// Do something here...
} else {
alert("Sorry: we didn't find "+bookTitle+" in our catalog");
}
In the first line of code, the indexOf() method returns either -1 if "bookTitle" is not found inside "catalog". If indexOf() found it, it will return zero or a positive integer; since we are adding 1, our condition will either be zero (no matches found by indexOf() ), or a positive number (at least one match found).
Or you can explicitly check the character position returned by indexOf() :
if( catalog.indexOf(bookTitle) > -1 ) { // ...
... But the purpose of the code in the first script has the advantage of being more immediately obvious, especially if you wrote the code yourself.
Searching recursively through strings with indexOf()
As implied by the script above, JavaScript's indexOf() method searches from left to right; there are several ways to force your script to iterate through the string if needed. The simplest, without using "regular expressions", is to use the character position index returned by indexOf() in conjunction with the substring() method: search the entire string with indexOf(), then search the substring starting at the index of the first match + the number of characters of the string you are looking for. Here is an example:
// Declare a string containing multiple hyphens:
var carter = "I-have-started-learning-JavaScript";
var numberOfHyphens = 0;
// Now loop through the string with indexOf():
for(var i=0, searchIndex=0; i<carter.length; ++i) {
searchIndex = carter.indexOf("-");
if(searchIndex==-1)
break; // Exit loop if indexOf() found no match
// Ok, add the new match indexOf() found:
++numberOfHyphens;
// Now make the string start after the match:
// (We will explain why you need add a 1)
carter = carter.substring( searchIndex + 1 );
}
// Return the number of matches indexOf() found
alert( "indexOf() found " + numberOfHyphens + " hyphen(s)" );
The script above returns the number of matches collected by indexOf() :
This
is of course
not the most efficient script, nor even the best use of indexOf(), but it illustrates how indexOf() works, and how you can leverage the results it returns. Let's now explain now why we added a 1
to our search index:
indexOf() returns the *starting* position of the matched string
The indexOf() method returns the first character at which started the string we were looking for: this means that, unless we add the length of the string we were looking for, we will keep looking at the same substring that starts with the string we are looking for. And since we never add numbers to the new start position index, we will be stuck in an infinite loop where indexOf() keeps returning zero (i.e. the string in which we are looking starts with the string we are looking for). While the indexOf() method would be satisfied if you always started looking one character further than the beginning of the last match, it is better practice (safer), to start at the end of the last match.
You can also use this type of recursion with the sibling method of indexOf(), the lastIndexOf() method: while indexOf() starts from the left of the string, lastIndexOf() starts from the end - this is the only difference, but a very handy combination of built-in functions to have. Surprisingly, several major web development and programming languages do not have an equivalent to JavaScript's lastIndexOf() method.
Test the indexOf() Method
Interactively test the indexOf() method by editing the JavaScript code below and clicking the Test indexOf() Method button.
Browser support for JavaScript indexOf() method | |||
---|---|---|---|