1403

I need to determine if a value exists in an array.

I am using the following function:

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] == obj) {
            return true;
        }
    }
    return false;
}

The above function always returns false.

The array values and the function call is as below:

arrValues = ["Sam","Great", "Sample", "High"]
alert(arrValues.contains("Sam"));
zx8754
  • 52,746
  • 12
  • 114
  • 209
Prasad
  • 58,881
  • 64
  • 151
  • 199
  • 2
    See also: http://stackoverflow.com/q/237104/1569 – Factor Mystic Feb 18 '11 at 21:08
  • 10
    The code works in Safari 4.0.2. BTW: I'd do a `===` comparison instead of just `==`. – Georg Schölly Jul 25 '09 at 08:45
  • 1
    "The above function always returns false." No it doesn't: The function works as expected - the error must be somewhere else. – Christoph Jul 25 '09 at 08:59
  • 5
    `Finally its worked. its due to improper trim of the comparing value. there was some space in the comparing value` (A comment from the asker, to the [accepted answer](http://stackoverflow.com/a/1181586/148412).) – ANeves Oct 01 '12 at 09:09
  • It works, you should have used `===` instead of `==` – hellol11 Apr 11 '16 at 15:40
  • For whoever is still struggling with it. The following took care of it for me: 1. Install lodash.includes by executing the following command: npm --save lodash.includes 2. Require lodash.includes: var includes = require('lodash.includes'); 3. use it like this: arrayBeingUsed.includes(valueToLookFor); (https://www.npmjs.com/package/lodash.includes) – Oliver Nov 22 '16 at 19:48
  • Related with better answer - http://stackoverflow.com/a/38073833/104380 – vsync Jan 05 '17 at 16:04
  • `["Admin", "Action", "WriteType"].find( (key) => { console.log(`key = `, key); return key === "KeyWord" } ); ` –  Aug 25 '17 at 07:00
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find –  Aug 25 '17 at 07:01
  • you can use Lodash _.some(arrValues,'Sam') => true /false – Akxaya Mar 21 '18 at 19:11
  • if(numbers.join('') == '') then it means array named 'numbers' is empty. – Priyanka Jun 17 '19 at 16:58
  • there is no contains method in javascript for array, you can use includes instead – Yang Wang Oct 17 '20 at 05:45

18 Answers18

1021

jQuery has a utility function for this:

$.inArray(value, array)

Returns index of value in array. Returns -1 if array does not contain value.

See also How do I check if an array includes an object in JavaScript?

Community
  • 1
  • 1
codeape
  • 97,830
  • 24
  • 159
  • 188
  • 170
    Don't let the name "inArray" fool you. As mentioned above (but of course I didn't read closely enough), returns -1 *(not false)* if the element doesn't exist. – Greg Bernhardt Apr 19 '11 at 20:13
  • 6
    @Steve Paul what is wrong with name? it does what it says: -1=it's NOT there, anything else= it's there – Jeffz Jun 22 '13 at 18:09
  • 135
    'inArray' implies that a boolean will be returned indicating whether the element could be found in the array. Therefore users may feel tempted to use the expression: if ($.inArray('myval', myarray)) {...} This will evaluate to true if 'myval' is NOT in myarray. Furthermore, it will evaluate to false if myval's index is 0. – Stephen Paul Jun 24 '13 at 05:11
  • 31
    The non-booleanness of `$.inArray`'s return definitely feels like a mistake on jQuery's part. Surely, it ought to be renamed to `$.indexOf`, if that's the function it's polyfilling? – ChaseMoskal Mar 07 '14 at 23:01
  • 5
    Works, but requires the jQuery framework. Not ideal if you're not using it otherwise. – donohoe Dec 30 '14 at 02:10
  • 7
    It's very easy to suggest that someone uses a JQuery method for everything javascript, but as the original question was for a javascript solution, then one should be provided in that manner – Dark Star1 Oct 01 '15 at 12:40
  • 2
    Does not work for `NaN` – Trevor Jan 05 '16 at 00:16
  • Also worth mentioning that $.inArray('0', ['0', '1', '2']) will return 0, which _should_ be true, but inside and if it evaluates to false. – Shahar Jan 23 '17 at 18:23
  • You could use a bitwise operator like `if (!~$.inArray(0, [13, 27, 35, 36, 37, 38, 39, 40])) {}`. The tilde (~) transforms -1 to 0 and 0 is equal to false in Javascript. – Martin James Jun 21 '18 at 12:34
1013
var contains = function(needle) {
    // Per spec, the way to identify NaN is that it is not equal to itself
    var findNaN = needle !== needle;
    var indexOf;

    if(!findNaN && typeof Array.prototype.indexOf === 'function') {
        indexOf = Array.prototype.indexOf;
    } else {
        indexOf = function(needle) {
            var i = -1, index = -1;

            for(i = 0; i < this.length; i++) {
                var item = this[i];

                if((findNaN && item !== item) || item === needle) {
                    index = i;
                    break;
                }
            }

            return index;
        };
    }

    return indexOf.call(this, needle) > -1;
};

You can use it like this:

var myArray = [0,1,2],
    needle = 1,
    index = contains.call(myArray, needle); // true

CodePen validation/usage

eyelidlessness
  • 62,413
  • 11
  • 90
  • 94
  • 4
    Note that indexOf on arrays is not implemented in IE, but you can define it yourself – RaYell Jul 25 '09 at 08:36
  • 9
    you should use a typed comparison with `===` to be compatible with the native implementation – Christoph Jul 25 '09 at 09:08
  • 3
    fixed the comparison and added the missing `return -1`; please note that according to the ES5 spec, this method will behave differently from the native one in case ofsigned zeroes and NaNs (see 15.4.4.14 and 9.12 vs. 11.9.6) – Christoph Jul 25 '09 at 09:26
  • I have tried all the answers given , but still returning false. – Prasad Jul 25 '09 at 10:52
  • 1
    Finally its worked. its due to improper trim of the comparing value. there was some space in the comparing value – Prasad Jul 25 '09 at 11:10
  • 4
    What version of IE does this answer refer to? – Vivian River Feb 24 '12 at 22:20
  • The shim should test if `i` is a property of `this`. – the system Mar 05 '13 at 19:12
  • 2
    Note that in Sharepoint 2010, WebParts can break if you implement an Array.Prototype: http://labs.steveottenad.com/type-mismatch-on-wpadder-js/ – wilsjd Apr 02 '13 at 15:21
  • @thesystem, that's an odd concern for a method of `Array.prototype` and an `i` that is numeric and bound by `0` and `this.length`. I think we can safely assume that `i` is a property of `this`, given those characteristics. I suppose it could be an issue if you call `Array.prototype.indexOf.call(someArbitraryObjectWithALengthProperty)`, but that would be true of the native method as well. – eyelidlessness Jun 23 '13 at 07:43
  • @wilsjd, I have been meaning to update this for some time, to warn against patching prototypes. – eyelidlessness Jun 23 '13 at 07:44
  • var i = -1, index; Can anyone explain this part? (it returns undefined if the needle is not found in the array) testing on IE8, works fine for firefox – Enrico Aug 06 '13 at 12:17
  • How about this: `~array.indexOf(value)` -- It'll be truthy if the value exists and falsy otherwhise. So you could do something like: `if (~array.indexOf(value)) { console.log('Found it!'); }` – gtramontina Jul 24 '14 at 17:18
  • @gtramontina, that is very "clever" but confusing to anyone who doesn't know what it does. In order to make it maintainable, you'd overcome your savings in code characters by documenting it with a comment. – eyelidlessness Jul 24 '14 at 20:32
  • @eyelidlessness I'd rather document it with tests. – gtramontina Jul 24 '14 at 22:29
  • @gtramontina, but if anyone else has to read your code, it will be confusing. If not, do whatever you want... but then that calls into question advocating it on a Q&A site. – eyelidlessness Jul 25 '14 at 01:19
  • @gtramontina Why would you do a bitwise not (~) rather than a logical not (!)? I guess in this case the end result is the same, but as the next person reading your code, I would spend a few minutes puzzling on that one, as I just did. – mhenry1384 Nov 21 '14 at 14:41
  • A logical not (`!`) on its own – i.e. `if (!array.indexOf(value))` – would fail the case where the element exists on the first position (`0`), as 0 is falsy. – gtramontina Nov 26 '14 at 00:32
  • Doesn't work for `NaN` – Trevor Jan 05 '16 at 00:14
  • @threed, that's a good catch, but I'm a little stumped about how best to fix it for SO users. I briefly edited the non-native implementation to handle `NaN`, then checked it in CodePen; I realized that the native `Array.prototype.indexOf` method (at least in Chrome) also doesn't support `NaN`. So on the one hand, the behavior is technically incorrect, but on the other hand it has parity with what the browser provides. I know how I'd solve it in my own projects (a wrapper function, completely sidestepping the native implementation for `NaN`), but I'm cautious about misdirecting SO users. – eyelidlessness Jan 05 '16 at 02:39
  • 1
    @threed, thinking more on this, I realize the actual *question* is not about `indexOf`, that was just an implementation detail. I'll more thoroughly update the answer. – eyelidlessness Jan 05 '16 at 02:40
  • Good call. I recommend taking a look at the MDN polyfill for the Array.includes method. – Trevor Jan 05 '16 at 02:42
  • @threed, I took a look at the MDN page, and I honestly found it hard to read. That said, I've updated my answer to handle `NaN` (and included the CodePen) – eyelidlessness Jan 05 '16 at 02:50
  • var numbers = [0,1,2,3,4,5,6,7,8,9]; return jQuery.inArray( parseInt(e.key), numbers )!=-1; – Afsal KK Dec 27 '16 at 07:38
  • 1
    [1, 2, 3].includes(2); Array.includes(val) is available since year 2016 – Udara Seneviratne Feb 21 '17 at 15:26
927

This is generally what the indexOf() method is for. You would say:

return arrValues.indexOf('Sam') > -1
Carlos
  • 5,991
  • 6
  • 43
  • 82
Gabriel Hurley
  • 39,690
  • 13
  • 62
  • 88
  • I really like that you can do this which is essentially the same thing as the jQuery answer above, but without jQuery - plus you can simplify it as Kenneth pointed out, although I couldn't make that work in the console. – Jason Cramer Jul 29 '15 at 00:08
  • 8
    `indexOf` does not work in – Doug S Oct 26 '15 at 00:23
  • 1
    Does not work with `NaN` – Trevor Jan 05 '16 at 00:09
  • 3
    I like how Kenneth J's comment has more upvotes than the answer. But good stuff - I've used indexOf() for strings, but I didn't know you could use it for arrays in general. – doubleDown Feb 04 '16 at 12:02
  • 2
    `return ~arrValues.indexOf('Sam')` will return `false` if element does not exist in array – Zychoo Jun 15 '16 at 08:47
  • IE support *can* matter if you're targeting certain countries where users use dilapidated hardware. – nikk wong Jan 10 '17 at 21:21
  • @SujayPhadke: Because money. https://www.sitepoint.com/browser-trends-january-2015-ie8-usage-triples/ . Depending on niche and target market, the percentage may vary. – Sebastian Mach Mar 25 '17 at 20:16
  • 3
    @SebastianMach and if all web devs just took a stand saying no... users will be forced to change. and helps companies save money since they don't have to hire IE developers – Sujay Phadke Mar 26 '17 at 04:25
  • 1
    @SujayPhadke: Unfortunately, that's an Utopia. For any group of people beyond a critical mass, there will never be perfect agreement. – Sebastian Mach Apr 08 '17 at 05:45
  • 1
    @SebastianMach agreed. But it has happened before, (recent past). Adobe Flash had a huge critical mass, no one can argue that. It took one company to make a logical tech argument to end flash on the web and bring in standards. – Sujay Phadke Apr 08 '17 at 06:19
  • @SujayPhadke: True. It was the company holding the de facto monopoly. Microsoft would be required to destroy IE. However, would they deploy such a mandatory uninstallation, there would be users outcrying (at least I bet so). – Sebastian Mach Apr 08 '17 at 14:04
  • @SujayPhadke Or the developers who make a stand will get fired and the company will hire new devs who can comply with IE. It goes both ways. – Anshul May 01 '17 at 20:07
  • "Doesn't work on – Fusseldieb May 07 '18 at 14:00
  • @DougS indexOf works in node.js, so awesome! –  May 09 '18 at 09:37
  • Works fine for latest browsers and also string literals. Superb! – Vijay Kumar Kanta Apr 25 '19 at 14:39
427

Array.prototype.includes()

In ES2016, there is Array.prototype.includes().

The includes() method determines whether an array includes a certain element, returning true or false as appropriate.

Example

["Sam", "Great", "Sample", "High"].includes("Sam"); // true

Support

According to kangax and MDN, the following platforms are supported:

  • Chrome 47
  • Edge 14
  • Firefox 43
  • Opera 34
  • Safari 9
  • Node 6

Support can be expanded using Babel (using babel-polyfill) or core-js. MDN also provides a polyfill:

if (![].includes) {
  Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
    'use strict';
    var O = Object(this);
    var len = parseInt(O.length) || 0;
    if (len === 0) {
      return false;
    }
    var n = parseInt(arguments[1]) || 0;
    var k;
    if (n >= 0) {
      k = n;
    } else {
      k = len + n;
      if (k < 0) {k = 0;}
    }
    var currentElement;
    while (k < len) {
      currentElement = O[k];
      if (searchElement === currentElement ||
         (searchElement !== searchElement && currentElement !== currentElement)) {
        return true;
      }
      k++;
    }
    return false;
  };
}
Dale
  • 5,607
  • 2
  • 22
  • 21
  • 3
    I'm tempted to post this answer across several javascript questions concerning multiple variable values or arrays. The polyfill from MDN is nice. – Nathan Goings Jul 03 '15 at 03:14
  • 3
    thanks for this! Babel polyfils it nicely :-) I remember 2 years ago jQuery was in any project and nowadays it's Babel :) big win for JavaScript community! There's table of what's available of ES7 already on many platforms including babel pollyfils http://kangax.github.io/compat-table/es2016plus/ – Lukas Liesis Jul 12 '16 at 09:52
143

It's almost always safer to use a library like lodash simply because of all the issues with cross-browser compatibilities and efficiency.

Efficiency because you can be guaranteed that at any given time, a hugely popular library like underscore will have the most efficient method of accomplishing a utility function like this.

_.includes([1, 2, 3], 3); // returns true

If you're concerned about the bulk that's being added to your application by including the whole library, know that you can include functionality separately:

var includes = require('lodash/collections/includes');

NOTICE: With older versions of lodash, this was _.contains() rather than _.includes().

Ryan McGeary
  • 235,892
  • 13
  • 95
  • 104
ncabral
  • 2,512
  • 1
  • 19
  • 20
  • 13
    @threed, you don't have to include the whole library. Partial functionality can be included with require('lodash/collections/contains'). – ncabral Jan 05 '16 at 04:22
  • 26
    FYI: With lodash 4 it's now `_.includes()` instead of `_.contains()`. – shadowhorst Apr 17 '16 at 16:44
  • 2
    helper libraries may seem convenient but tend to change (too) often, see comment above "lodash 4 '_.contains()' is now '_.includes()'" – anneb Feb 25 '17 at 16:58
  • @anneb that could be said about any library. that's why you have semver and dependency management. – ncabral Feb 27 '17 at 16:45
  • In Lodash versions prior to 2.x _.include() is an alias for _.contains() and there is no _.includes() defined. As of ver. 3.x, _.include() and _.contains() are both aliases for _includes(). But as of ver. 4.x, there is only _.includes() and no more other aliases. – fwiw Jul 04 '18 at 13:53
  • I once wanted to retrieve values from an object via a case-insensitive index look up. lodash doesn't (didn't at the time at least) have a performant way of doing this. So you can't just assume that because it's a popular library that it will always be performant for your specific requirement – Zach Smith Aug 03 '18 at 13:02
  • @ZachSmith I understand. But emphasis on the "specific requirement" there. I only mentioned this as an "almost always" applicable answer. And case-insensitive index lookups are the exception to the norm - hence, lodash isn't optimised for it. – ncabral Dec 02 '18 at 01:57
53

Since ECMAScript6, one can use Set:

var myArray = ['A', 'B', 'C'];
var mySet = new Set(myArray);
var hasB = mySet.has('B'); // true
var hasZ = mySet.has('Z'); // false
kuujinbo
  • 9,272
  • 3
  • 44
  • 57
Nicolas
  • 739
  • 7
  • 7
47

tl;dr

function includes(k) {
  for(var i=0; i < this.length; i++){
    if( this[i] === k || ( this[i] !== this[i] && k !== k ) ){
      return true;
    }
  }
  return false;
}

Example

function includes(k) {
  for(var i=0; i < this.length; i++){
    if( this[i] === k || ( this[i] !== this[i] && k !== k ) ){
      return true;
    }
  }
  return false;
}

function log(msg){
  $('#out').append('<div>' + msg + '</div>');  
}

var arr = [1, "2", NaN, true];
arr.includes = includes;

log('var arr = [1, "2", NaN, true];');
log('<br/>');
log('arr.includes(1): ' + arr.includes(1));
log('arr.includes(2): ' + arr.includes(2));
log('arr.includes("2"): ' + arr.includes("2"));
log('arr.includes(NaN): ' + arr.includes(NaN));
log('arr.includes(true): ' + arr.includes(true));
log('arr.includes(false): ' + arr.includes(false));
#out{
  font-family:monospace;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=out></div>

Longer Answer

I know this question isn't really about whether or not to extend built-in objects, but the attempt of the OP and the comments on this answer highlight that debate. My comment from Feb 12, '13 cites an article that outlines this debate really well, however that link broke and I can't edit the original comment because too much time has passed, so I include it here.

If you're looking to extend the built-in Array object with a contains method, probably the best and most responsible way to do this would be to use this polyfill from MDN. (See also this section of the MDN article on Prototypical inheritance, which explains that "The only good reason for extending a built-in prototype is to backport the features of newer JavaScript engines; for example Array.forEach, etc.")

if (!Array.prototype.includes) {
  Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {
    'use strict';
    var O = Object(this);
    var len = parseInt(O.length) || 0;
    if (len === 0) {
      return false;
    }
    var n = parseInt(arguments[1]) || 0;
    var k;
    if (n >= 0) {
      k = n;
    } else {
      k = len + n;
      if (k < 0) {k = 0;}
    }
    var currentElement;
    while (k < len) {
      currentElement = O[k];
      if (searchElement === currentElement ||
         (searchElement !== searchElement && currentElement !== currentElement)) {
        return true;
      }
      k++;
    }
    return false;
  };
}

Don't want strict equality, or want to choose?

function includes(k, strict) {
  strict = strict !== false; // default is true
  // strict = !!strict; // default is false
  for(var i=0; i < this.length; i++){
    if( (this[i] === k && strict) || 
        (this[i] == k && !strict) ||
        (this[i] !== this[i] && k !== k)
    ) {
      return true;
    }
  }
  return false;
}
Trevor
  • 13,085
  • 13
  • 76
  • 99
  • 4
    Isn't this technique of augmenting built-in types frowned upon? – Sahat Yalkabov Oct 11 '12 at 03:49
  • 3
    Buggy: `[1,2,4].contains([].contains)` is true. Also unnecessarily slow due to the same bug. Avoid for..in over arrays. – Eamon Nerbonne Jan 17 '13 at 15:02
  • @Eamon Nerbonne: I just pasted that code into jsfiddle.net and got false. Am I doing something wrong. Also, could you elaborate on how this bug slows the code down? Finally, I wasn't aware that there is a performance difference for "for..in" loops. Could you explain or direct me towards an article where I could read more? – Trevor Jan 18 '13 at 17:59
  • @threed totally untrue: "This is a very common practice and is used extensively by jQuery" - they create new prototypes for some objects they use, but NOT modify built-in prototypes – naugtur Feb 11 '13 at 13:18
22

My little contribution:

function isInArray(array, search)
{
    return array.indexOf(search) >= 0;
}

//usage
if(isInArray(my_array, "my_value"))
{
    //...
}
Matías Cánepa
  • 5,770
  • 4
  • 57
  • 97
20

If you have access to ECMA 5 you can use the some method.

MDN SOME Method Link

arrValues = ["Sam","Great", "Sample", "High"];

function namePresent(name){
  return name === this.toString();
}
// Note:
// namePresent requires .toString() method to coerce primitive value
// i.e. String {0: "S", 1: "a", 2: "m", length: 3, [[PrimitiveValue]]: "Sam"}
// into
// "Sam"

arrValues.some(namePresent, 'Sam');
=> true;

If you have access to ECMA 6 you can use the includes method.

MDN INCLUDES Method Link

arrValues = ["Sam","Great", "Sample", "High"];

arrValues.includes('Sam');
=> true;
SoEzPz
  • 14,958
  • 8
  • 61
  • 64
18

Given the implementation of indexOf for IE (as described by eyelidlessness):

Array.prototype.contains = function(obj) {
    return this.indexOf(obj) > -1;
};
rlovtang
  • 4,860
  • 2
  • 30
  • 30
12

You can use _.indexOf method or if you don't want to include whole Underscore.js library in your app, you can have a look how they did it and extract necessary code.

    _.indexOf = function(array, item, isSorted) {
    if (array == null) return -1;
    var i = 0, l = array.length;
    if (isSorted) {
      if (typeof isSorted == 'number') {
        i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
      } else {
        i = _.sortedIndex(array, item);
        return array[i] === item ? i : -1;
      }
    }
    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
    for (; i < l; i++) if (array[i] === item) return i;
    return -1;
  };
Wojciech Bednarski
  • 6,033
  • 9
  • 49
  • 73
10

Another option would be to use Array.some (if available) in the following way:

Array.prototype.contains = function(obj) {
  return this.some( function(e){ return e === obj } );
}

The anonymous function passed to Array.some will return true if and only if there is an element in the array that is identical to obj. Absent such an element, the function will not return true for any of the elements of the array, so Array.some will return false as well.

Hunan Rostomyan
  • 2,176
  • 2
  • 22
  • 31
8

Wow, there are a lot of great answers to this question.

I didn't see one that takes a reduce approach so I'll add it in:

var searchForValue = 'pig';

var valueIsInArray = ['horse', 'cat', 'dog'].reduce(function(previous, current){
    return previous || searchForValue === current ? true : false;
}, false);

console.log('The value "' + searchForValue + '" is in the array: ' + valueIsInArray);

Here's a fiddle of it in action.

Chris Schmitz
  • 20,160
  • 30
  • 81
  • 137
  • I was actually thinking about going this route, but it still has to transverse the entire array even when a result is found. – cgatian Mar 10 '16 at 14:06
  • 1
    @cgatian that's a good point. It's def something to keep in mind when picking which method to use. You could potentially wrap the reduce statement in a `try` `catch` block and throw an exception once you've found the value, but if you do that I think you lose some of the simplicity that the functional approach gives you. – Chris Schmitz Mar 10 '16 at 14:16
6

The answer provided didn't work for me, but it gave me an idea:

Array.prototype.contains = function(obj)
    {
        return (this.join(',')).indexOf(obj) > -1;
    }

It isn't perfect because items that are the same beyond the groupings could end up matching. Such as my example

var c=[];
var d=[];
function a()
{
    var e = '1';
    var f = '2';
    c[0] = ['1','1'];
    c[1] = ['2','2'];
    c[2] = ['3','3'];
    d[0] = [document.getElementById('g').value,document.getElementById('h').value];

    document.getElementById('i').value = c.join(',');
    document.getElementById('j').value = d.join(',');
    document.getElementById('b').value = c.contains(d);
}

When I call this function with the 'g' and 'h' fields containing 1 and 2 respectively, it still finds it because the resulting string from the join is: 1,1,2,2,3,3

Since it is doubtful in my situation that I will come across this type of situation, I'm using this. I thought I would share incase someone else couldn't make the chosen answer work either.

Kakoroat
  • 93
  • 1
  • 1
  • 1
    This solution seems very fragile and prone to error in all but the most narrow cases. Imagine, for example, using this array: `var arr = ["Smith, Reed", "Jackson, Frank"]; arr.contains(searchTerm);` Image that some user accidentally typed `"Reed,Jackson"` instead of `"Reed, Jackson"` in some text field that searched through this array. This algorithm would return a false positive and the user would think that `Reed, Jackson` actually existed when it doesn't. Cases like this are why this algorithm is much more prone to bugs. – Trevor Jan 05 '16 at 00:33
5

Using array .map function that executes a function for every value in an array seems cleanest to me.

Ref: Array.prototype.map()

This method can work well both for simple arrays and for arrays of objects where you need to see if a key/value exists in an array of objects.

function inArray(myArray,myValue){
    var inArray = false;
    myArray.map(function(key){
        if (key === myValue){
            inArray=true;
        }
    });
    return inArray;
};

var anArray = [2,4,6,8]
console.log(inArray(anArray, 8)); // returns true
console.log(inArray(anArray, 1)); // returns false

function inArrayOfObjects(myArray,myValue,objElement){
    var inArray = false;
    myArray.map(function(arrayObj){
        if (arrayObj[objElement] === myValue) {
            inArray=true;
        }
    });
    return inArray;
};

var objArray = [{id:4,value:'foo'},{id:5,value:'bar'}]
console.log(inArrayOfObjects(objArray, 4, 'id')); // returns true
console.log(inArrayOfObjects(objArray, 'bar', 'value')); // returns true
console.log(inArrayOfObjects(objArray, 1, 'id')); // returns false
Nikhil Vartak
  • 5,002
  • 3
  • 26
  • 32
Ian Vasquez
  • 91
  • 1
  • 3
2
function setFound(){   
 var l = arr.length, textBox1 = document.getElementById("text1");
    for(var i=0; i<l;i++)
    {
     if(arr[i]==searchele){
      textBox1 .value = "Found";
      return;
     }
    }
    textBox1 .value = "Not Found";
return;
}

This program checks whether the given element is found or not. Id text1 represents id of textbox and searchele represents element to be searched (got fron user); if you want index, use i value

codefreaK
  • 3,584
  • 5
  • 34
  • 65
deeban
  • 99
  • 1
  • 11
1

The simplest solution for a contains function, would be a function that looks like this :

var contains = function (haystack, needle) {
    return !!~haystack.indexOf(needle);
}

Ideally, you wouldn't make this a stand-alone function, though, but part of a helper library :

var helper = {};

helper.array = {
    contains : function (haystack, needle) {
        return !!~haystack.indexOf(needle);
    }, 
    ...
};

Now, if you happen to be one of those unlucky people who still needs to support IE<9 and thus can't rely on indexOf, you could use this polyfill, which I got from the MDN :

if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(searchElement, fromIndex) {
    var k;
    if (this == null) {
      throw new TypeError('"this" is null or not defined');
    }
    var o = Object(this);
    var len = o.length >>> 0;
    if (len === 0) {
      return -1;
    }
    var n = +fromIndex || 0;

    if (Math.abs(n) === Infinity) {
      n = 0;
    }
    if (n >= len) {
      return -1;
    }
    k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
    while (k < len) {
      if (k in o && o[k] === searchElement) {
        return k;
      }
      k++;
    }
    return -1;
  };
}
John Slegers
  • 45,213
  • 22
  • 199
  • 169
-7

I prefer simplicity:

var days = [1, 2, 3, 4, 5];
if ( 2 in days ) {console.log('weekday');}
valeri
  • 13
  • 3
  • 9
    He wants to find a value in an array, not an index. So this won't do the job, even if it is simple. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in – Ashley Davis Jun 18 '14 at 22:20