views:

27710

answers:

9

What is the best way to find if an object is in an array ?

This is the best way I know:

function include(arr, obj) {
  for(var i=0; i<arr.length; i++) {
    if (arr[i] == obj) return true;
  }
}

include([1,2,3,4], 3); // true
include([1,2,3,4], 6); // undefined
+44  A: 
Vinko Vrsalovic
That works so well, and so obviously, that I'm surprised I didn't know about it, and surprised that I've never seen it in other languages with array objects.
davenpcj
Java hast it as well http://java.sun.com/j2se/1.4.2/docs/api/java/util/ArrayList.html#indexOf(java.lang.Object)
Vinko Vrsalovic
.NET has it http://msdn.microsoft.com/en-us/library/system.array.indexof.aspx
Vinko Vrsalovic
Array.indexOf was added in JavaScript 1.6 - not all browsers will have it. Make sure you do things the slow way if it's not present.
fenomas
Make your you add it instead of doing them the old way, check Daniel's answer
Vinko Vrsalovic
The only thing I'd do to make it even better is to replace "!= -1" with "< 0", and make it a new method of the array class - but things this simple and concise are nearly a work of art.
matt lohkamp
Array.indexOf() is not present in IE6's JavaScript implementation. I can't believe this answer has gotten so many up-votes.
roosteronacid
@matt lohkamp: > 0 would return false if obj is the first element of arr. As roosteronacid said, it would be a very good idea to edit this answer to include Daniel James's answer about IE support.
Joel Anair
To give credit where it's due, 'my' version is a slightly tweaked modification of Erik Arvidsson's indexOf implementation.
Daniel James
The `Array.prototype.indexOf` method is not present even on IE8, it was just added on IE9 Platform Preview 3. I would recommend to include the implementation made by [Mozilla](https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf), it is [ECMAScript 5 standard compliant](http://ecma262-5.com/ELS5_HTML.htm#Section_15.4.4.14)
CMS
+2  A: 

If the array is unsorted, there isn't really a better way (aside from using the above-mentioned indexOf, which I think amounts to the same thing). If the array is sorted, you can do a binary search, which works like this:

  1. Pick the middle element of the array.
  2. Is the element you're looking for bigger than the element you picked? If so, you've eliminated the bottom half of the array. If it isn't, you've eliminated the top half.
  3. Pick the middle element of the remaining half of the array, and continue as in step 2, eliminating halves of the remaining array. Eventually you'll either find your element or have no array left to look through.

Binary search runs in time proportional to the logarithm of the length of the array, so it can be much faster than looking at each individual element.

assortedslog
You probably should mention that this approach would be faster on large, sorted arrays than small ones.
roosteronacid
+2  A: 

Here's some meta-knowledge for you - if you want to know what you can do with an Array, check the documentation - here's the Array page for Mozilla

http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array

There you'll see reference to indexOf, added in Javascript 1.6

Paul Dixon
Weird URL for a manual containing information about Javascript 1.8 and beyond! :)
Vinko Vrsalovic
A: 

It depends on your purpose. If you program for the Web, avoid indexOf, it isn't supported by IE6 (lot of them still used!), or do conditional use:

if (yourArray.indexOf !== undefined) result = yourArray.indexOf(target);
else result = customSlowerSearch(yourArray, target);

indexOf is probably coded in native code, so faster than anything you can do in JS (except binary search/dichotomy if the array is appropriate). Note: question of taste, but I would do a return false; at the end of your routine, to return a true boolean...

PhiLho
+6  A: 

First, implement indexOf in javascript for browser's that don't already have it, for example see Erik Arvidsson's array extras (also, the associated blog post). And then you can use indexOf without worrying about browser support. Here's a slightly optimised version of his indexOf implementation:

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (obj, fromIndex) {
        if (fromIndex == null) {
            fromIndex = 0;
        } else if (fromIndex < 0) {
            fromIndex = Math.max(0, this.length + fromIndex);
        }
        for (var i = fromIndex, j = this.length; i < j; i++) {
            if (this[i] === obj)
                return i;
        }
        return -1;
    };
}

It's changed to store the length so that it doesn't need to look it up every iteration. But the difference isn't huge. A less general purpose function might be faster:

var include = Array.prototype.indexOf ?
    function(arr, obj) { return arr.indexOf(obj) !== -1; } :
    function(arr, obj) {
        for(var i = -1, j = arr.length; ++i < j;)
            if(arr[i] === obj) return true;
        return false;
    };

I prefer using the standard function and leaving this sort of micro-optimization for when it's really needed. But if you're keen on micro-optimization I adapted the benchmarks that roosterononacid linked to in the comments, to benchmark searching in arrays. They're pretty crude though, a full investigation would test arrays with different types, different lengths and finding objects that occur in different places.

Daniel James
The code examples you are linking to are slow on large arrays. See the comments in my implementation example of a hasItem() function.
roosteronacid
Take a look at these benchmarks: http://blogs.sun.com/greimer/resource/loop-test.htm For-loops are slow. But I guess the arrays used in the benchmarks are pretty huge :)
roosteronacid
Updated my post, using your specialized-function pattern.
roosteronacid
http://blogs.sun.com/greimer/resource/loop-test.html
roosteronacid
I agree. I'm also quite pragmatic. But in the case of optimizing the very basics of the language, I think it's good design to implement functionality as performance-effective as possible.
roosteronacid
+5  A: 

If you are using jQuery:

http://api.jquery.com/jQuery.inArray/

GerManson
+1  A: 

Here's a flexible approach to searching arrays of objects using whichever object property or properties you desire: link text

I've just used it myself :)

Enjoy...

Daniel
A: 

For some reason I was getting a js error (in both Firefox 3.6.6 and IE 7 using the for loop construct in Daniel's sample:

for (var i = fromIndex, j = this.length; i < j; i++) {
        if (this[i] === obj)
            return i;
    }

I changed it to evaluate the array length outside the loop beforehand:

 var len = this.length;
 for (var i = fromIndex; i < j; i++) {
            if (this[i] === obj)
            return i;
 }

and then it worked.

Anyone know why I would get an error?

Zac Imboden
A: 

New Document

var arr=new Array(5); for(var da=0;da

//how can i searchwhether an elemnt is there in the given list or not using flag.

Ashish
post a new question for this.
Anurag
sorry but this is not an answer to the question, please make a new question
zimbatm