2

How can I check whether a particular element is inside an array? I don't want to manually write a loop for this; instead I want to use a JavaScript built-in function, maybe something equivalent to

new Array(0,1,2,3,6,9,12,15,18).Contains(5)  //return false
new Array(0,1,2,3,6,9,12,15,18).Contains(1)   //return true
0

6 Answers 6

12

The Array object does have an indexOf function, that will return -1 if the object does not exist. However, IE does not support this function.

Regardless, how do you think it is going to locate the item under the scenes? It will have to loop! Just because there's a built-in function does not mean that it is magical.

Sign up to request clarification or add additional context in comments.

4 Comments

+1 for mentioning that it uses a loop internally. I think a lot of people don't get that, especially people coming from Ruby, in my experience. :)
Well, there is a loop, but loops in Ruby, for example are going to be faster if they're native than in they're written in Ruby itself. For example, that particular check would be coded in C, running much more quickly than a loop written in Ruby, so while native methods might not be magical, they're definitely faster. The same is true for JavaScript's built-in methods.
@Andrew Noyes: Yeah, but when someone says "I want to do this without using a loop", that's technically impossible. ;)
The fact that hand-written loops would have to be interpreted is the only reason that they would be slower.
4

You could also write an extension method, as explained in this thread.

Array.prototype.contains = function(obj) {
  var i = this.length;
  while (i--) {
    if (this[i] === obj) {
      return true;
    }
  }
  return false;
}
And now you can simply use the following:

alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false

3 Comments

You could utilize indexOf here as well, at least for the implementations that support it!
BTW, the firefox algorithm for internally locating an item in an array (indexOf) is available at the link in my answer. I'm certain it will be faster than this while loop.
@Josh: I doubt it's any faster. There are a lot of checks to make sure the right arguments are passed, etc, so I don't see why it would be faster. @DeadHead: Why is it not portable? The source code is right here: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
2

As @Josh Stodola said, the indexOf function is what you need, but this function was introduced on JavaScript 1.6, for compatibility you can use this implementation from the Mozilla team, is exactly the one used in Firefox and SpiderMonkey:

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

Source: MDC

1 Comment

I already had a link to this, but thanks for posting the code!
1

Looks like a job for jQuery.inArray

inArray: function( elem, array ) {
    for ( var i = 0, length = array.length; i < length; i++ )
    // Use === because on IE, window == document
        if ( array[ i ] === elem )
            return i;

    return -1;
}

2 Comments

Hey, jQuery.inArray use loops in its guts
I edited this, and added the inArray function directly from the jQuery source, just for reference.
1

There is no such method in javascript.

Some library (e.g. jquery) have similar method, but they use loops internally.

Comments

1

Ah, there is a way not to loop and it is pretty simple, people just do not think outside the box.

Array.prototype.contains = function(){     
    var joined = this.join("-~-");
    var re = new RegExp("(^|-~-)" + arguments[0] + "($|-~-)");   
    return joined.match(re) !== null;
}

var arr = ["a","b","c","d"];   
alert(arr.contains("a"));
alert(arr.contains("b"));
alert(arr.contains("c"));
alert(arr.contains("d"));
alert(arr.contains("e"));

Loop mom, no loops!

2 Comments

Could be true, but it is not looping in the user written JavaScript code. :)
Nice one, Eric! This has to perform terribly, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.