4998

What is the most concise and efficient way to find out if a JavaScript array contains a value?

This is the only way I know to do it:

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

Is there a better and more concise way to accomplish this?

This is very closely related to Stack Overflow question Best way to find an item in a JavaScript Array? which addresses finding objects in an array using indexOf.

9
  • 66
    just tested: your way is actually the fastest for across browsers: jsperf.com/find-element-in-obj-vs-array/2 (apart from pre-saving a.length in a variable) while using indexOf (as in $.inArray) is much slower Commented Jul 2, 2012 at 11:56
  • 24
    many have replied that the Array#indexOf is your best choice here. But if you want something that can be correctly cast to Boolean, use this: ~[1,2,3].indexOf(4) will return 0 which will evaluate as false, whereas ~[1,2,3].indexOf(3) will return -3 which will evaluate as true. Commented Oct 2, 2013 at 7:59
  • 13
    ~ is not what you want to use to convert to a boolean, for that you need !. But in this case you want to check equality with -1, s o the function might endreturn [1,2,3].indexOf(3) === -1; ~ is a binary not, it will invert each bit of the value individually. Commented Jun 20, 2014 at 12:49
  • 19
    @Iordvlad [1,2,3].indexOf(4) will actually return -1. As @mcfedr pointed out, ~ is the bitwise-NOT operator, see ES5 11.4.8. Thing is, since the binary representation of -1 consists of only 1's, it's complement is 0, which evaluates as false. The complement of any other number will be non-zero, hence true. So, ~ works just fine and is often used in conjunction with indexOf. Commented Mar 14, 2015 at 5:35
  • 9
    The title is misleading. Where is the [[1,2],[3,4]].includes([3,4]) ? Commented Apr 2, 2017 at 9:20

63 Answers 63

6

    function countArray(originalArray) {
     
    	var compressed = [];
    	// make a copy of the input array
    	var copyArray = originalArray.slice(0);
     
    	// first loop goes over every element
    	for (var i = 0; i < originalArray.length; i++) {
     
    		var count = 0;	
    		// loop over every element in the copy and see if it's the same
    		for (var w = 0; w < copyArray.length; w++) {
    			if (originalArray[i] == copyArray[w]) {
    				// increase amount of times duplicate is found
    				count++;
    				// sets item to undefined
    				delete copyArray[w];
    			}
    		}
     
    		if (count > 0) {
    			var a = new Object();
    			a.value = originalArray[i];
    			a.count = count;
    			compressed.push(a);
    		}
    	}
     
    	return compressed;
    };
    
    // It should go something like this:
    
    var testArray = new Array("dog", "dog", "cat", "buffalo", "wolf", "cat", "tiger", "cat");
    var newArray = countArray(testArray);
    console.log(newArray);

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

Comments

6

use Array.prototype.includes for example:

const fruits = ['coconut', 'banana', 'apple']

const doesFruitsHaveCoconut = fruits.includes('coconut')// true

console.log(doesFruitsHaveCoconut)

maybe read this documentation from MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

Comments

5

Here's how Prototype does it:

/**
 *  Array#indexOf(item[, offset = 0]) -> Number
 *  - item (?): A value that may or may not be in the array.
 *  - offset (Number): The number of initial items to skip before beginning the
 *      search.
 *
 *  Returns the position of the first occurrence of `item` within the array &mdash; or
 *  `-1` if `item` doesn't exist in the array.
**/
function indexOf(item, i) {
  i || (i = 0);
  var length = this.length;
  if (i < 0) i = length + i;
  for (; i < length; i++)
    if (this[i] === item) return i;
  return -1;
}

Also see here for how they hook it up.

Comments

5

By no means the best, but I was just getting creative and adding to the repertoire.

Do not use this

Object.defineProperty(Array.prototype, 'exists', {
  value: function(element, index) {

    var index = index || 0

    return index === this.length ? -1 : this[index] === element ? index : this.exists(element, ++index)
  }
})


// Outputs 1
console.log(['one', 'two'].exists('two'));

// Outputs -1
console.log(['one', 'two'].exists('three'));

console.log(['one', 'two', 'three', 'four'].exists('four'));

2 Comments

What should you use if not this?
@bryc maybe the accepted solution, or another solution from here. If you don't care much for performance, than you can use this
5

You can also use this trick:

var arrayContains = function(object) {
  return (serverList.filter(function(currentObject) {
    if (currentObject === object) {
      return currentObject
    }
    else {
      return false;
    }
  }).length > 0) ? true : false
}

1 Comment

this seems convoluted. 'object' is a poor name, 'item' might be better. the filter function logic should just be return currentObject === item; and the ternary operator is uncessary..
5
  1. Either use Array.indexOf(Object).
  2. With ECMA 7 one can use the Array.includes(Object).
  3. With ECMA 6 you can use Array.find(FunctionName) where FunctionName is a user defined function to search for the object in the array.

    Hope this helps!

Comments

5

Use indexOf()

You can use the indexOf() method to check whether a given value or element exists in an array or not. The indexOf() method returns the index of the element inside the array if it is found, and returns -1 if it not found. Let's take a look at the following example:

var fruits = ["Apple", "Banana", "Mango", "Orange", "Papaya"];
var a = "Mango";
checkArray(a, fruits);


function checkArray(a, fruits) {
  // Check if a value exists in the fruits array
  if (fruits.indexOf(a) !== -1) {
    return document.write("true");
  } else {
    return document.write("false");
  }
}

Use include() Method

ES6 has introduced the includes() method to perform this task very easily. But, this method returns only true or false instead of index number:

var fruits = ["Apple", "Banana", "Mango", "Orange", "Papaya"];
alert(fruits.includes("Banana")); // Outputs: true
alert(fruits.includes("Coconut")); // Outputs: false
alert(fruits.includes("Orange")); // Outputs: true
alert(fruits.includes("Cherry")); // Outputs: false

For further reference checkout here

Comments

4

Use:

Array.prototype.contains = function(x){
  var retVal = -1;

  // x is a primitive type
  if(["string","number"].indexOf(typeof x)>=0 ){ retVal = this.indexOf(x);}

  // x is a function
  else if(typeof x =="function") for(var ix in this){
    if((this[ix]+"")==(x+"")) retVal = ix;
  }

  //x is an object...
  else {
    var sx=JSON.stringify(x);
    for(var ix in this){
      if(typeof this[ix] =="object" && JSON.stringify(this[ix])==sx) retVal = ix;
    }
  }

  //Return False if -1 else number if numeric otherwise string
  return (retVal === -1)?false : ( isNaN(+retVal) ? retVal : +retVal);
}

I know it's not the best way to go, but since there is no native IComparable way to interact between objects, I guess this is as close as you can get to compare two entities in an array. Also, extending Array object might not be a wise thing to do, but sometimes it's OK (if you are aware of it and the trade-off).

1 Comment

Late note: this doesn't work with, say, contains([{ a: 1, b: 2 }], { b: 2, a: 1 }) because the stringified objects maintain the order of the properties.
3

As others have mentioned you can use Array.indexOf, but it isn't available in all browsers. Here's the code from https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf to make it work the same in older browsers.

indexOf is a recent addition to the ECMA-262 standard; as such it may not be present in all browsers. You can work around this by inserting the following code at the beginning of your scripts, allowing use of indexOf in implementations which do not natively support it. This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming Object, TypeError, Number, Math.floor, Math.abs, and Math.max have their original value.

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
        "use strict";
        if (this == null) {
            throw new TypeError();
        }
        var t = Object(this);
        var len = t.length >>> 0;
        if (len === 0) {
            return -1;
        }
        var n = 0;
        if (arguments.length > 1) {
            n = Number(arguments[1]);
            if (n != n) { // shortcut for verifying if it's NaN
                n = 0;
            } else if (n != 0 && n != Infinity && n != -Infinity) {
                n = (n > 0 || -1) * Math.floor(Math.abs(n));
            }
        }
        if (n >= len) {
            return -1;
        }
        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
        for (; k < len; k++) {
            if (k in t && t[k] === searchElement) {
                return k;
            }
        }
        return -1;
    }
}

Comments

3

Or this solution:

Array.prototype.includes = function (object) {
  return !!+~this.indexOf(object);
};

1 Comment

Late note: this will now overwrite the existing, native includes function, which is one of the reasons altering built-in objects' prototypes is considered bad practice.
3

Using idnexOf() it is a good solution, but you should hide embedded implementation indexOf() function which returns -1 with ~ operator:

function include(arr,obj) { 
    return !!(~arr.indexOf(obj)); 
} 

Comments

3

I was working on a project that I needed a functionality like python set which removes all duplicates values and returns a new list, so I wrote this function maybe useful to someone

function set(arr) {
    var res = [];
    for (var i = 0; i < arr.length; i++) {
        if (res.indexOf(arr[i]) === -1) {
            res.push(arr[i]);
        }
    }
    return res;
}

Comments

3

If you're working with ES6 You can use a set:

function arrayHas( array, element ) {
    const s = new Set(array);
    return s.has(element)
}

This should be more performant than just about any other method

1 Comment

How is it more performant? At the very least you have to construct the set, which is O(n) (you have to iterate over the array). Just doing linear search (like indexOf does) is also O(n), but only in the worst case. The average case complexity is more like n/2, since if the array includes the element, you'll likely stop somewhere in the middle. Therefore, this method is, on average, slower than Array#includes and Array#indexOf.
3

I recommended to use underscore library because its return the value and its supported for all browsers.

underscorejs

 var findValue = _.find(array, function(item) {
    return item.id == obj.id;
 });

Comments

3

In Addition to what others said, if you don't have a reference of the object which you want to search in the array, then you can do something like this.

let array = [1, 2, 3, 4, {"key": "value"}];

array.some((element) => JSON.stringify(element) === JSON.stringify({"key": "value"})) // true

array.some((element) => JSON.stringify(element) === JSON.stringify({})) // true

Array.some returns true if any element matches the given condition and returns false if none of the elements matches the given condition.

1 Comment

Late note: this doesn't work with, say, contains([{ a: 1, b: 2 }], { b: 2, a: 1 }) because the stringified objects maintain the order of the properties.
3

Adding a unique item to a another list

searchResults: [
                {
                    name: 'Hello',
                    artist: 'Selana',
                    album: 'Riga',
                    id: 1,
                },
                {
                    name: 'Hello;s',
                    artist: 'Selana G',
                    album: 'Riga1',
                    id: 2,
                },
                {
                    name: 'Hello2',
                    artist: 'Selana',
                    album: 'Riga11',
                    id: 3,
                }
            ],
            playlistTracks: [
              {
                name: 'Hello',
                artist: 'Mamunuus',
                album: 'Riga',
                id: 4,
              },
              {
                name: 'Hello;s',
                artist: 'Mamunuus G',
                album: 'Riga1',
                id: 2,
              },
              {
                name: 'Hello2',
                artist: 'Mamunuus New',
                album: 'Riga11',
                id: 3,
              }
            ],
            playlistName: "New PlayListTrack",
        };
    }

    // Adding an unique track in the playList
    addTrack = track => {
      if(playlistTracks.find(savedTrack => savedTrack.id === track.id)) {
        return;
      }
      playlistTracks.push(track);

      this.setState({
        playlistTracks
      })
    };

1 Comment

What does it have to do with the question asked?
3

This may be a detailed and easy solution.

//plain array
var arr = ['a', 'b', 'c'];
var check = arr.includes('a');
console.log(check); //returns true
if (check)
{
   // value exists in array
   //write some codes
}

// array with objects
var arr = [
      {x:'a', y:'b'},
      {x:'p', y:'q'}
  ];

// if you want to check if x:'p' exists in arr
var check = arr.filter(function (elm){
    if (elm.x == 'p')
    {
       return elm; // returns length = 1 (object exists in array)
    }
});

// or y:'q' exists in arr
var check = arr.filter(function (elm){
    if (elm.y == 'q')
    {
       return elm; // returns length = 1 (object exists in array)
    }
});

// if you want to check, if the entire object {x:'p', y:'q'} exists in arr
var check = arr.filter(function (elm){
    if (elm.x == 'p' && elm.y == 'q')
    {
       return elm; // returns length = 1 (object exists in array)
    }
});

// in all cases
console.log(check.length); // returns 1

if (check.length > 0)
{
   // returns true
   // object exists in array
   //write some codes
}

Comments

3

Object.keys for getting all property names of the object and filter all values that exact or partial match with specified string.

function filterByValue(array, string) {
  return array.filter(o =>
    Object.keys(o).some(k => o[k].toLowerCase().includes(string.toLowerCase())));
}

const arrayOfObject = [{
  name: 'Paul',
  country: 'Canada',
}, {
  name: 'Lea',
  country: 'Italy',
}, {
  name: 'John',
  country: 'Italy'
}];

console.log(filterByValue(arrayOfObject, 'lea')); // [{name: 'Lea', country: 'Italy'}]
console.log(filterByValue(arrayOfObject, 'ita')); // [{name: 'Lea', country: 'Italy'}, {name: 'John', country: 'Italy'}]

You can also filter by specific key such as.

Object.keys(o).some(k => o.country.toLowerCase().includes(string.toLowerCase())));

Now you can just check array count after filtered to check value contains or not.

Hope it's helpful.

Comments

3

The best default method to check if value exist in array JavaScript is some()

Array.prototype.some()

The some() method tests whether at least one element in the array passes the test implemented by the provided function. It returns true if, in the array, it finds an element for which the provided function returns true; otherwise it returns false. It doesn't modify the array.

const array = [1, 2, 3, 4, 5];

// checks whether an element is even
const even = (element) => element % 2 === 0;

console.log(array.some(even));
// expected output: true

The some method is the best one in Browser compatibility Browser compatibility

For more documentation Array.prototype.some() - JavaScript | MDN

Also you can use other two method is find() and includes(). with those method you can get your result but not the best one.

Array.prototype.find() - JavaScript | MDN

Array.prototype.includes() - JavaScript | MDN

Comments

3

There are several ways to find out. You can use inbuilt Array methods. The most prominently used is Array find method.

const arr1 = [1, 2, 3, 4, 5]
const result = arr1.find(ele => ele === 4)
console.log(result) //4

const result2 = arr1.find(ele => ele === 6)
console.log(result2) //undefined
/* 
If the element is present inside the array
then it will return the first element that
satisfies the given condition. Otherwise
undefined will return.
*/

And if your array is sorted, then you can use binary search on the array.

const recursiveBinarySearch = (arr, target, first = 0, last = arr.length - 1) => {
  let firstIndex = first;
  let lastIndex = last;
  if (lastIndex < firstIndex) return -1;
  const midIndex = Math.floor((firstIndex + lastIndex) / 2);
  if (arr[midIndex] === target) return midIndex;
  if (arr[midIndex] < target) return recursiveBinarySearch(arr, target, midIndex + 1, last);
  if (arr[midIndex] > target) return recursiveBinarySearch(arr, target, firstIndex, midIndex - 1);
};
console.log(recursiveBinarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10)); //9
console.log(recursiveBinarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2)); // 1
console.log(recursiveBinarySearch(['bird', 'cat', 'dog', 'fish'], 'dog')); // 2

Comments

2

Similar thing: Finds the first element by a "search lambda":

Array.prototype.find = function(search_lambda) {
  return this[this.map(search_lambda).indexOf(true)];
};

Usage:

[1,3,4,5,8,3,5].find(function(item) { return item % 2 == 0 })
=> 4

Same in coffeescript:

Array.prototype.find = (search_lambda) -> @[@map(search_lambda).indexOf(true)]

3 Comments

This certainly is much more flexible than many of the other approaches. If one is uncomfortable with the prototype one might consider something like var positionIf = function (predicate,sequence) {return sequence.map(predicate).indexOf(true);};
A more efficient way to implement this method would be to use a loop and stop applying search_lambda once something is found.
Late note: This code overwrites the native implementation of find with this one. One of the reasons to avoid altering the prototype of built-in objects.
2

I looked through submitted answers and got that they only apply if you search for the object via reference. A simple linear search with reference object comparison.

But lets say you don't have the reference to an object, how will you find the correct object in the array? You will have to go linearly and deep compare with each object. Imagine if the list is too large, and the objects in it are very big containing big pieces of text. The performance drops drastically with the number and size of the elements in the array.

You can stringify objects and put them in the native hash table, but then you will have data redundancy remembering these keys cause JavaScript keeps them for 'for i in obj', and you only want to check if the object exists or not, that is, you have the key.

I thought about this for some time constructing a JSON Schema validator, and I devised a simple wrapper for the native hash table, similar to the sole hash table implementation, with some optimization exceptions which I left to the native hash table to deal with. It only needs performance benchmarking... All the details and code can be found on my blog: http://stamat.wordpress.com/javascript-quickly-find-very-large-objects-in-a-large-array/ I will soon post benchmark results.

The complete solution works like this:

var a = {'a':1,
 'b':{'c':[1,2,[3,45],4,5],
 'd':{'q':1, 'b':{'q':1, 'b':8},'c':4},
 'u':'lol'},
 'e':2};

 var b = {'a':1, 
 'b':{'c':[2,3,[1]],
 'd':{'q':3,'b':{'b':3}}},
 'e':2};

 var c = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

 var hc = new HashCache([{a:3, b:2, c:5}, {a:15, b:2, c:'foo'}]); //init

 hc.put({a:1, b:1});
 hc.put({b:1, a:1});
 hc.put(true);
 hc.put('true');
 hc.put(a);
 hc.put(c);
 hc.put(d);
 console.log(hc.exists('true'));
 console.log(hc.exists(a));
 console.log(hc.exists(c));
 console.log(hc.exists({b:1, a:1}));
 hc.remove(a);
 console.log(hc.exists(c));

Comments

1

Simple solution : ES6 Features "includes" method

let arr = [1, 2, 3, 2, 3, 2, 3, 4];

  arr.includes(2) // true

  arr.includes(93) // false

Comments

1

Using RegExp:

console.log(new RegExp('26242').test(['23525', '26242', '25272'].join(''))) // true

Comments

1

If you're just trying to check whether a value is included in a collection, It would be more appropriate to use a Set, As Arrays can have duplicate values whereas Sets cannot. Also, Replacing array.includes with set.has improves the performance from O(n2) to O(n). This will be useful when you have to look up multiple values for the same Set. so if you're just going to look up a single value, there's no benefit to use set.has, you can just use an array.includes.

Created a jsbench demo, You can run this to check the performance.

Screenshot of the test execution :

enter image description here

1 Comment

I don't know why, but when I run this .includes is faster.
1

This is how you can do.

const arr = [1, 2, 3, 4, 5];

console.log(arr.includes(3)); // true
console.log(arr.includes(6)); // false

Comments

1

see lots of results


const array = [1, 2, 3, 4, 2]

console.log(
   array.indexOf(2),          // 1
   array.filter(e => e == 2), // [ 2, 2 ]
   array.includes(2),         // true
   array.find(e => e == 2)    // 2
)
// view does not match
console.log(
   array.indexOf(12),          // -1
   array.filter(e => e == 12), // []
   array.includes(12),         // false
   array.find(e => e == 12)    // undefined
)
// match
console.log(
   array.indexOf(2) != -1,               // true
   array.filter(e => e == 2).length > 0, // true
   array.includes(2),                    // true
   array.find(e => e == 2) != undefined  // true
)

Comments

1
function checkArrayItem(Array, search_key, search_value){
   return Array.filter(x => x[search_key] == search_value).length > 0 ? true : false;
}

Comments

0

You can use findIndex function to check if an array has a specific value.

arrObj.findIndex(obj => obj === comparedValue) !== -1;

Returns true if arrObj contains comparedValue, false otherwise.

Comments

0

Complexity O(n/2)

You can use any library function but I did it using core JavaScript. We search first search the element in the middle if we get return true, else we search the element in array from left to center and right to center in same time . So it will atmost O(n/2) complexity. And it will return true or false, indicate it exist or not.You can return index number instead of Boolean value

let isExist = (arr, element)=> {
  let index = -1;
  if ((arr.length % 2 != 0) && arr[(arr.length-1)/2]===element) {
    index = 1;
    return true;
  }
  for(let i=0; i<Math.ceil(arr.length-1/2); i++){
    if (arr[i]===element || (arr[arr.length-i]===element)) {
      index = i;
      break;
    }
  }
  return (index<0)? false : true;
}



let array = ['apple', 'ball', 'cat', 'dog', 'egg']

console.log(isExist(array, 'yellow'));
//Result false because yellow doesn't exist in array
console.log(isExist(array, 'cat'));
//Result true because yellow exist in array

1 Comment

You can use any library function but I did it using core JavaScript. We search first search the element in the middle if we get return true, else we search the element in array from left to center and right to center in same time . So it will atmost O(n/2) complexity. And it will return true or false, indicate it exist or not.You can return index number instead of Boolean value

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.