How to determine if Javascript array contains an object with an attribute that equals a given value?

JavascriptArrays

Javascript Problem Overview


I have an array like

vendors = [{
    Name: 'Magenic',
    ID: 'ABC'
  },
  {
    Name: 'Microsoft',
    ID: 'DEF'
  } // and so on... 
];

How do I check this array to see if "Magenic" exists? I don't want to loop, unless I have to. I'm working with potentially a couple thousand records.

Javascript Solutions


Solution 1 - Javascript

No need to reinvent the wheel loop, at least not explicitly (using arrow functions, modern browsers only):

if (vendors.filter(e => e.Name === 'Magenic').length > 0) {
  /* vendors contains the element we're looking for */
}

or, better yet, as it allows the browser to stop as soon as one element is found that matches, so it's going to be faster:

if (vendors.some(e => e.Name === 'Magenic')) {
  /* vendors contains the element we're looking for */
}

EDIT: If you need compatibility with lousy browsers then your best bet is:

if (vendors.filter(function(e) { return e.Name === 'Magenic'; }).length > 0) {
  /* vendors contains the element we're looking for */
}

Solution 2 - Javascript

2018 edit: This answer is from 2011, before browsers had widely supported array filtering methods and arrow functions. Have a look at CAFxX's answer.

There is no "magic" way to check for something in an array without a loop. Even if you use some function, the function itself will use a loop. What you can do is break out of the loop as soon as you find what you're looking for to minimize computational time.

var found = false;
for(var i = 0; i < vendors.length; i++) {
    if (vendors[i].Name == 'Magenic') {
        found = true;
        break;
    }
}

Solution 3 - Javascript

No loop necessary. Three methods that come to mind:

Array.prototype.some()

This is the most exact answer for your question, i.e. "check if something exists", implying a bool result. This will be true if there are any 'Magenic' objects, false otherwise:

let hasMagenicVendor = vendors.some( vendor => vendor['Name'] === 'Magenic' )

Array.prototype.filter()

This will return an array of all 'Magenic' objects, even if there is only one (will return a one-element array):

let magenicVendors = vendors.filter( vendor => vendor['Name'] === 'Magenic' )

If you try to coerce this to a boolean, it will not work, as an empty array (no 'Magenic' objects) is still truthy. So just use magenicVendors.length in your conditional.

Array.prototype.find()

This will return the first 'Magenic' object (or undefined if there aren't any):

let magenicVendor = vendors.find( vendor => vendor['Name'] === 'Magenic' );

This coerces to a boolean okay (any object is truthy, undefined is falsy).


Note: I'm using vendor["Name"] instead of vendor.Name because of the weird casing of the property names.

Note 2: No reason to use loose equality (==) instead of strict equality (===) when checking the name.

Solution 4 - Javascript

The accepted answer still works but now we have an ECMAScript 6 native methods [Array.find][1] and [Array.some][2] to achieve the same effect.

Array.some

Use some If you only want to determine if an element exists i.e. you need a true/false determination.

Quoting MDN:

>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.

Array.find

Use find if you want to get the matched object from array else returns undefined.

Quoting MDN:

> The find() method returns the value of the first element in the provided array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.

var arr = [];
var item1 = {
    id: 21,
    label: 'Banana',
};
var item2 = {
    id: 22,
    label: 'Apple',
};
arr.push(item1, item2);

/* note : data is the actual object that matched search criteria 
  or undefined if nothing matched */

var data = arr.find(function(ele) {
    return ele.id === 21;
});

if (data) {
    console.log('found');
    console.log(data); // This is entire object i.e. `item` not boolean
}


/* note : doesExist is a boolean thats true or false depending on of whether the data was found or not */
var doesExist = arr.some(function(ele) {
    return ele.id === 21;
});


See my jsfiddle link There is a polyfill for IE provided by mozilla

Solution 5 - Javascript

Here's the way I'd do it

const found = vendors.some(item => item.Name === 'Magenic');

array.some() method checks if there is at least one value in an array that matches criteria and returns a boolean. From here on you can go with:

if (found) {
// do something
} else {
// do something else
}

Solution 6 - Javascript

Unless you want to restructure it like this:

vendors = {
    Magenic: {
      Name: 'Magenic',
      ID: 'ABC'
     },
    Microsoft: {
      Name: 'Microsoft',
      ID: 'DEF'
    } and so on... 
};

to which you can do if(vendors.Magnetic)

You will have to loop

Solution 7 - Javascript

As per ECMAScript 6 specification, you can use findIndex.

const magenicIndex = vendors.findIndex(vendor => vendor.Name === 'Magenic');

magenicIndex will hold either 0 (which is the index in the array) or -1 if it wasn't found.

Solution 8 - Javascript

As the OP has asked the question if the key exists or not.

A more elegant solution that will return boolean using ES6 reduce function can be

const magenicVendorExists =  vendors.reduce((accumulator, vendor) => (accumulator||vendor.Name === "Magenic"), false);

Note: The initial parameter of reduce is a false and if the array has the key it will return true.

Hope it helps for better and cleaner code implementation

Solution 9 - Javascript

May be too late, but javascript array has two methods some and every method that returns a boolean and can help you achieve this.

I think some would be most appropriate for what you intend to achieve.

vendors.some( vendor => vendor['Name'] !== 'Magenic' )

Some validates that any of the objects in the array satisfies the given condition.

vendors.every( vendor => vendor['Name'] !== 'Magenic' )

Every validates that all the objects in the array satisfies the given condition.

Solution 10 - Javascript

You cannot without looking into the object really.

You probably should change your structure a little, like

vendors = {
    Magenic:   'ABC',
    Microsoft: 'DEF'
};

Then you can just use it like a lookup-hash.

vendors['Microsoft']; // 'DEF'
vendors['Apple']; // undefined

Solution 11 - Javascript

Testing for array elements:

JS Offers array functions which allow you to achieve this relatively easily. They are the following:

  1. Array.prototype.filter: Takes a callback function which is a test, the array is then iterated over with is callback and filtered according to this callback. A new filtered array is returned.
  2. Array.prototype.some: Takes a callback function which is a test, the array is then iterated over with is callback and if any element passes the test, the boolean true is returned. Otherwise false is returned

The specifics are best explained via an example:

Example:

vendors = [
    {
      Name: 'Magenic',
      ID: 'ABC'
     },
    {
      Name: 'Microsoft',
      ID: 'DEF'
    } //and so on goes array... 
];

// filter returns a new array, we instantly check if the length 
// is longer than zero of this newly created array
if (vendors.filter(company => company.Name === 'Magenic').length ) {
  console.log('I contain Magenic');
}

// some would be a better option then filter since it directly returns a boolean
if (vendors.some(company => company.Name === 'Magenic')) {
  console.log('I also contain Magenic');
}

Browser support:

These 2 function are ES6 function, not all browsers might support them. To overcome this you can use a polyfill. Here is the polyfill for Array.prototype.some (from MDN):

if (!Array.prototype.some) {
  Array.prototype.some = function(fun, thisArg) {
    'use strict';

    if (this == null) {
      throw new TypeError('Array.prototype.some called on null or undefined');
    }

    if (typeof fun !== 'function') {
      throw new TypeError();
    }

    var t = Object(this);
    var len = t.length >>> 0;

    for (var i = 0; i < len; i++) {
      if (i in t && fun.call(thisArg, t[i], i, t)) {
        return true;
      }
    }

    return false;
  };
}

Solution 12 - Javascript

const check = vendors.find((item)=>item.Name==='Magenic')

console.log(check)

Try this code.

If the item or element is present then the output will show you that element. If it is not present then the output will be 'undefined'.

Solution 13 - Javascript

2021 Solution*

Lodash .some (docs) is a clean solution, if you use the _matchesProperty (docs) shorthand:

_.some(VENDORS, ['Name', 'Magenic'])

Explanation

This will iterate through the VENDORS Array looking for an element Object with the Name key having a value of the String 'Magenic'. Once it finds this element, it returns true and stops iterating. If it doesn't find the element after looking through the entire Array, it returns false.

Code snippet

const VENDORS = [{ Name: 'Magenic', ID: 'ABC' }, { Name: 'Microsoft', ID: 'DEF' }];

console.log(_.some(VENDORS, ['Name', 'Magenic'])); // true

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

* Note that this uses the popular lodash library to achieve the simplest/shortest possible solution. I'm offering this as an alternative to the existing vanilla JS solutions, for those who are interested.

Solution 14 - Javascript

Functions map, filter, find, and similar are slower than the simple loop. For me they also less readable than the simple loop and harder to debug. Using them looks like a kind of irrational ritual.

Better have something like this:

 arrayHelper = {
     arrayContainsObject: function (array, object, key){
         for (let i = 0; i < array.length; i++){
            if (object[key] === array[i][key]){
                 return true;
            }
         }
         return false;
     }
     
   };

And use it like this with given OP example:

    vendors = [{
    Name: 'Magenic',
    ID: 'ABC'
     },
     {
    Name: 'Microsoft',
    ID: 'DEF'
     } 
  ];

let abcObject = {ID: 'ABC', Name: 'Magenic'};

let isContainObject = arrayHelper.arrayContainsObject(vendors, abcObject, 'ID');

Solution 15 - Javascript

You have to loop, there is no way around it.

function seekVendor(vendors, name) {
  for (var i=0, l=vendors.length; i<l; i++) {
    if (typeof vendors[i] == "object" && vendors[i].Name === name) {
      return vendors[i];
    }
  }
}

Of course you could use a library like linq.js to make this more pleasing:

Enumerable.From(vendors).Where("$.Name == 'Magenic'").First();

(see jsFiddle for a demo)

I doubt that linq.js will be faster than a straight-forward loop, but it certainly is more flexible when things get a little more complicated.

Solution 16 - Javascript

Correct me if i'm wrong.. i could have used forEach method like this,

var found=false;
vendors.forEach(function(item){
   if(item.name === "name"){
       found=true;
       
   }
});

Nowadays i'm used to it ,because of it simplicity and self explanatory word. Thank you.

Solution 17 - Javascript

My approach to solving this problem is to use ES6 and creating a function that does the check for us. The benefit of this function is that it can be reusable through out your project to check any array of objects given the key and the value to check.

ENOUGH TALK, LET'S SEE THE CODE

Array

const ceos = [
  {
    name: "Jeff Bezos",
    company: "Amazon"
  }, 
  {
    name: "Mark Zuckerberg",
    company: "Facebook"
  }, 
  {
    name: "Tim Cook",
    company: "Apple"
  }
];

Function

const arrayIncludesInObj = (arr, key, valueToCheck) => {
  return arr.some(value => value[key] === valueToCheck);
}

Call/Usage

const found = arrayIncludesInObj(ceos, "name", "Tim Cook"); // true

const found = arrayIncludesInObj(ceos, "name", "Tim Bezos"); // false

Solution 18 - Javascript

if you're using jquery you can take advantage of grep to create array with all matching objects:

var results = $.grep(vendors, function (e) {
    return e.Name == "Magenic";
});

and then use the results array:

for (var i=0, l=results.length; i<l; i++) {
    console.log(results[i].ID);
}

Solution 19 - Javascript

You can use lodash. If lodash library is too heavy for your application consider chunking out unnecessary function not used.

let newArray = filter(_this.props.ArrayOne, function(item) {
                    return find(_this.props.ArrayTwo, {"speciesId": item.speciesId});
                });

This is just one way to do this. Another one can be:

var newArray=  [];
     _.filter(ArrayOne, function(item) {
                        return AllSpecies.forEach(function(cItem){
                        	if (cItem.speciesId == item.speciesId){
                          	newArray.push(item);
                          }
                        }) 
                    });

console.log(arr);

The above example can also be rewritten without using any libraries like:

var newArray=  [];
ArrayOne.filter(function(item) {
                return ArrayTwo.forEach(function(cItem){
                	if (cItem.speciesId == item.speciesId){
                  	newArray.push(item);
                  }
                }) 
            });
console.log(arr);

Hope my answer helps.

Solution 20 - Javascript

Many answers here are good and pretty easy. But if your array of object is having a fixed set of value then you can use below trick:

Map all the name in a object.

vendors = [
    {
      Name: 'Magenic',
      ID: 'ABC'
     },
    {
      Name: 'Microsoft',
      ID: 'DEF'
    }
];

var dirtyObj = {}
for(var count=0;count<vendors.length;count++){
   dirtyObj[vendors[count].Name] = true //or assign which gives you true.
}

Now this dirtyObj you can use again and again without any loop.

if(dirtyObj[vendor.Name]){
  console.log("Hey! I am available.");
}

Solution 21 - Javascript

To compare one object to another, I combine a for in loop (used to loop through objects) and some(). You do not have to worry about an array going out of bounds etc, so that saves some code. Documentation on .some can be found here

var productList = [{id: 'text3'}, {id: 'text2'}, {id: 'text4', product: 'Shampoo'}]; // Example of selected products
var theDatabaseList = [{id: 'text1'}, {id: 'text2'},{id: 'text3'},{id:'text4', product: 'shampoo'}];	
var  objectsFound = [];

for(let objectNumber in productList){
	var currentId = productList[objectNumber].id;	
	if (theDatabaseList.some(obj => obj.id === currentId)) {
        // Do what you need to do with the matching value here
		objectsFound.push(currentId);
	}
}
console.log(objectsFound);

An alternative way I compare one object to another is to use a nested for loop with Object.keys().length to get the amount of objects in the array. Code below:

var productList = [{id: 'text3'}, {id: 'text2'}, {id: 'text4', product: 'Shampoo'}]; // Example of selected products
var theDatabaseList = [{id: 'text1'}, {id: 'text2'},{id: 'text3'},{id:'text4', product: 'shampoo'}];	
var objectsFound = [];

for(var i = 0; i < Object.keys(productList).length; i++){
		for(var j = 0; j < Object.keys(theDatabaseList).length; j++){
		if(productList[i].id === theDatabaseList[j].id){
			objectsFound.push(productList[i].id);
		}		
	}
}
console.log(objectsFound);

To answer your exact question, if are just searching for a value in an object, you can use a single for in loop.

var vendors = [
	{
	  Name: 'Magenic',
	  ID: 'ABC'
	 },
	{
	  Name: 'Microsoft',
	  ID: 'DEF'
	} 
];

for(var ojectNumbers in vendors){
	if(vendors[ojectNumbers].Name === 'Magenic'){
		console.log('object contains Magenic');
	}
}

Solution 22 - Javascript

Alternatively you can do:

const find = (key, needle) => return !!~vendors.findIndex(v => (v[key] === needle));

Solution 23 - Javascript

Example:

Result: without2([{id:1},{id:1},{id:2}],{id:2})

Solution 24 - Javascript

You can try this its work for me.

const _ = require('lodash');

var arr = [
  {
    name: 'Jack',
    id: 1
  },
  {
    name: 'Gabriel',
    id: 2
  },
  {
    name: 'John',
    id: 3
  }
]

function findValue(arr,value) {
  return _.filter(arr, function (object) {
    return object['name'].toLowerCase().indexOf(value.toLowerCase()) >= 0;
  });
}

console.log(findValue(arr,'jack'))
//[ { name: 'Jack', id: 1 } ]

Solution 25 - Javascript

const a = [{one:2},{two:2},{two:4}]
const b = a.filter(val => "two" in val).length;
if (b) {
   ...
}

Solution 26 - Javascript

Simplest method so far

if(vendors.findIndex(item => item.Name == "Magenic") == -1){
//not found item
}else{
//found item 
}

Solution 27 - Javascript

I would rather go with regex.

If your code is as follows,

vendors = [
    {
      Name: 'Magenic',
      ID: 'ABC'
     },
    {
      Name: 'Microsoft',
      ID: 'DEF'
    }
];

I would recommend

/"Name":"Magenic"/.test(JSON.stringify(vendors))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDavid LozziView Question on Stackoverflow
Solution 1 - JavascriptCAFxXView Answer on Stackoverflow
Solution 2 - JavascriptAlex TurpinView Answer on Stackoverflow
Solution 3 - JavascriptboxtrainView Answer on Stackoverflow
Solution 4 - JavascriptTeaCoderView Answer on Stackoverflow
Solution 5 - JavascriptMirza LekaView Answer on Stackoverflow
Solution 6 - JavascriptKeith.AbramoView Answer on Stackoverflow
Solution 7 - JavascriptLucas BentoView Answer on Stackoverflow
Solution 8 - JavascriptJay ChakraView Answer on Stackoverflow
Solution 9 - JavascriptAkinjiola ToniView Answer on Stackoverflow
Solution 10 - JavascriptjAndyView Answer on Stackoverflow
Solution 11 - JavascriptWillem van der VeenView Answer on Stackoverflow
Solution 12 - JavascriptHisham KuntawalaView Answer on Stackoverflow
Solution 13 - JavascriptJBallinView Answer on Stackoverflow
Solution 14 - JavascriptyurinView Answer on Stackoverflow
Solution 15 - JavascriptTomalakView Answer on Stackoverflow
Solution 16 - JavascriptNerdy SidView Answer on Stackoverflow
Solution 17 - Javascriptrotimi-bestView Answer on Stackoverflow
Solution 18 - JavascriptEitanView Answer on Stackoverflow
Solution 19 - JavascriptAbhay ShiroView Answer on Stackoverflow
Solution 20 - JavascriptjesusvermaView Answer on Stackoverflow
Solution 21 - JavascriptSpangleView Answer on Stackoverflow
Solution 22 - JavascriptBrunoWestView Answer on Stackoverflow
Solution 23 - Javascriptbehzad abbasiView Answer on Stackoverflow
Solution 24 - JavascriptjenishView Answer on Stackoverflow
Solution 25 - Javascriptuser1665355View Answer on Stackoverflow
Solution 26 - JavascriptnhCoderView Answer on Stackoverflow
Solution 27 - Javascriptsangwook kimView Answer on Stackoverflow