[javascript] How to determine if object is in array

I need to determine if an object already exists in an array in javascript.

eg (dummycode):

var carBrands = [];

var car1 = {name:'ford'};
var car2 = {name:'lexus'};
var car3 = {name:'maserati'};
var car4 = {name:'ford'};

carBrands.push(car1);
carBrands.push(car2);
carBrands.push(car3);
carBrands.push(car4);

now the "carBrands" array contains all instances. I'm now looking a fast solution to check if an instance of car1, car2, car3 or car4 is already in the carBrands array.

eg:

var contains =  carBrands.Contains(car1); //<--- returns bool.

car1 and car4 contain the same data but are different instances they should be tested as not equal.

Do I have add something like a hash to the objects on creation? Or is there a faster way to do this in Javascript.

I am looking for the fastest solution here, if dirty, so it has to be ;) In my app it has to deal with around 10000 instances.

no jquery

This question is related to javascript

The answer is


I would use a generic iterator of property/value over the array. No jQuery required.

arr = [{prop1: 'val1', prop2: 'val2'}, {prop1: 'val3', prop2: 'val4'}];

objectPropInArray(arr, 'prop1', 'val3'); // <-- returns true

function objectPropInArray(list, prop, val) {
  if (list.length > 0 ) {
    for (i in list) {
      if (list[i][prop] === val) {
        return true;
      }
    }
  }
  return false;  
}

You can just use the equality operator: ==. Objects are checked by reference by default, so you don't even need to use the === operator.

try this, just make sure you're using the correct variable reference in the place of car1:

var i, car, l = cars.length;

for (i = 0; i < l; i++)
{
  if ((car = cars[i]) == car1)
  {
    break;
  }
  else car = null;
}

Edit to add:

An array extension was mentioned, so here's the code for it:

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

Note that I'm caching the length value, as the Array's length property is actually an accessor, which is marginally slower than an internal variable.


I used underscore javascript library to tweak this issue.

function containsObject(obj, list) {
 var res = _.find(list, function(val){ return _.isEqual(obj, val)});
 return (_.isObject(res))? true:false;
}

please refer to underscore.js documentation for the underscore functions used in the above example.

note: This is not a pure javascript solution. Shared for educational purposes.


This function is to check for a unique field. Arg 1: the array with selected data Arg 2: key to check Arg 3: value that must be "validated"

function objectUnique( array, field, value )
{
    var unique = true;
    array.forEach(function ( entry )
    {
        if ( entry[field] == value )
        {
            unique = false;
        }
    });

    return unique;
}

Having been recently bitten by the FP bug reading many wonderful accounts of how neatly the functional paradigm fits with Javascript

I replicate the code for completeness sake and suggest two ways this can be done functionally.

    var carBrands = [];

  var car1 = {name:'ford'};
  var car2 = {name:'lexus'};
  var car3 = {name:'maserati'};
  var car4 = {name:'ford'};
  var car5 = {name:'toyota'};

  carBrands.push(car1);
  carBrands.push(car2);
  carBrands.push(car3);
  carBrands.push(car4);

  // ES6 approach which uses the includes method (Chrome47+, Firefox43+)

  carBrands.includes(car1) // -> true
  carBrands.includes(car5) // -> false

If you need to support older browsers use the polyfill, it seems IE9+ and Edge do NOT support it. Located in polyfill section of MSDN page

Alternatively I would like to propose an updated answer to cdhowie

// ES2015 syntax
function containsObject(obj, list) {

    return list.some(function(elem) {
      return elem === obj
    })
}

// or ES6+ syntax with cool fat arrows
function containsObject(obj, list) {

    return list.some(elem => elem === obj)
}

You could use jQuery's grep method:

$.grep(carBrands, function(obj) { return obj.name == "ford"; });

But as you specify no jQuery, you could just make a derivative of the function. From the source code:

function grepArray( elems, callback, inv ) {  
    var ret = [];  

    // Go through the array, only saving the items  
    // that pass the validator function  
    for ( var i = 0, length = elems.length; i < length; i++ ) {  
        if ( !inv !== !callback( elems[ i ], i ) ) {  
            ret.push( elems[ i ] );  
        }  
    }  

    return ret;  
}  

grepArray(carBrands, function(obj) { return obj.name == "ford"; });

You could try sorting the array based on a property, like so:

carBrands = carBrands.sort(function(x,y){
  return (x == y) ? 0 : (x > y) ? 1 : -1;
});

Then you can use an iterative routine to check whether

carBrands[Math.floor(carBrands.length/2)] 
// change carBrands.length to a var that keeps 
// getting divided by 2 until result is the target 
// or no valid target exists

is greater or lesser than the target, and so on, which will let you go through the array quickly to find whether the object exists or not.


try Array.prototype.some()

MDN Array.prototype.some


    function isBiggerThan10(element, index, array) {
      return element > 10;
    }
    [2, 5, 8, 1, 4].some(isBiggerThan10);  // false
    [12, 5, 8, 1, 4].some(isBiggerThan10); // true


i know this is an old post, but i wanted to provide a JQuery plugin version and my code.

// Find the first occurrence of object in list, Similar to $.grep, but stops searching 
function findFirst(a,b){
var i; for (i = 0; i < a.length; ++i) { if (b(a[i], i)) return a[i]; } return undefined;
}

usage:

var product = $.findFirst(arrProducts, function(p) { return p.id == 10 });

Why don't you use the indexOf method of javascript arrays?

Check this out: MDN indexOf Arrays

Simply do:

carBrands.indexOf(car1);

It will return you the index (position in the array) of car1. It will return -1 if car1 was not found in the array.

http://jsfiddle.net/Fraximus/r154cd9o

Edit: Note that in the question, the requirements are to check for the same object referenced in the array, and NOT a new object. Even if the new object is identical in content to the object in the array, it is still a different object. As mentioned in the comments, objects are passed by reference in JS and the same object can exist multiple times in multiple structures.
If you want to create a new object and check if the array contains objects identical to your new one, this answer won't work (Julien's fiddle below), if you want to check for that same object's existence in the array, then this answer will work. Check out the fiddles here and in the comments.