There isn't any need to reinvent the wheel loop, at least not explicitly.
Use some as it allows the browser to stop as soon as one element is found that matches:
if (vendors.some(e => e.Name === 'Magenic')) {
// We found at least one object that we're looking for!
}
or the equivalent (in this case) with find, which returns the found object instead of a boolean:
if (vendors.find(e => e.Name === 'Magenic')) {
// Usually the same result as above, but find returns the element itself
}
If you'd like to get the position of that element, use findIndex:
const i = vendors.findIndex(e => e.Name === 'Magenic');
if (i > -1) {
// We know that at least 1 object that matches has been found at the index i
}
If you need to get all of the objects that match:
if (vendors.filter(e => e.Name === 'Magenic').length > 0) {
// The same result as above, but filter returns all objects that match
}
If you need compatibility with really old browsers that don't support arrow functions, then your best bet is:
if (vendors.filter(function(e) { return e.Name === 'Magenic'; }).length > 0) {
// The same result as above, but filter returns all objects that match and we avoid an arrow function for compatibility
}
Answer from CAFxX on Stack OverflowThere isn't any need to reinvent the wheel loop, at least not explicitly.
Use some as it allows the browser to stop as soon as one element is found that matches:
if (vendors.some(e => e.Name === 'Magenic')) {
// We found at least one object that we're looking for!
}
or the equivalent (in this case) with find, which returns the found object instead of a boolean:
if (vendors.find(e => e.Name === 'Magenic')) {
// Usually the same result as above, but find returns the element itself
}
If you'd like to get the position of that element, use findIndex:
const i = vendors.findIndex(e => e.Name === 'Magenic');
if (i > -1) {
// We know that at least 1 object that matches has been found at the index i
}
If you need to get all of the objects that match:
if (vendors.filter(e => e.Name === 'Magenic').length > 0) {
// The same result as above, but filter returns all objects that match
}
If you need compatibility with really old browsers that don't support arrow functions, then your best bet is:
if (vendors.filter(function(e) { return e.Name === 'Magenic'; }).length > 0) {
// The same result as above, but filter returns all objects that match and we avoid an arrow function for compatibility
}
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;
}
}
Videos
It's true that object lookup occurs in constant time - O(1) - so using object properties instead of an array is one option, but if you're just trying to check whether a value is included in a collection, it would be more appropriate to use a Set, which is a (generally unordered) collection of values, which can also be looked up in linear time. (Using a plain object instead would require you to have values in addition to your keys, which you don't care about - so, use a Set instead.)
const set = new Set(['foo', 'bar']);
console.log(set.has('foo'));
console.log(set.has('baz'));
This will be useful when you have to look up multiple values for the same Set. But, adding items to the Set (just like adding properties to an object) is O(N), so if you're just going to look up a single value, once, there's no benefit to this nor the object technique, and you may as well just use an array includes test.
Updated 04/29/2020
As the commenter rightly pointed out it would seem V8 was optimizing out the array includes calls. An updated version that assigns to a var and uses it produces more expected results. In that case Object address is fastest, followed by Set has and in a distant third is Array includes (on my system / browser).
All the same, I do stand by my original point, that if making micro-optimizations it is worth testing assumptions. Just make sure your tests are valid ;)
Original
Well. Despite the obvious expectation that Object address and Set has should outperform Array includes, benchmarks against Chrome indicate that implementation trumps expectation.
In the benches I ran against Chrome Array includes was far and away the best performer.
I also tested locally with Node and got more expected results. In that Object address wins, followed closely by Set has, then Array includes was marginally slower than both.
Bottom line is, if you're making micro-optimizations (not recommending that) it's worth benchmarking rather than assuming which might be best for your particular case. Ultimately it comes down to the implementation, as your question implies. So optimizing for the target platform is key.
Here's the results I got:
Node (12.6.0):
ops for Object address 7804199
ops for Array includes 5200197
ops for Set has 7178483
Chrome (75.0):
https://jsbench.me/myjyq4ixs1/1

includes essentially checks if any element === the element you're searching for. In case of objects, === means literally the same object, as in the same reference (same place in memory), not the same shape.
var a1 = { name: 'a' }
var a2 = { name: 'a' }
console.log(a1 === a2) // false because they are not the same object in memory even if they have the same data
But if you search for an object that is actually in the array it works:
var a1 = { name: 'a' }
var a2 = { name: 'a' }
var array = [a1, a2]
console.log(array.includes(a1)) // true because the object pointed to by a1 is included in this array
Piping
let check = [{name: 'trent'}, {name: 'jason'}]
.map(item => item.name)
.includes('trent');
Simple & fast
let check = [{name: 'trent'}, {name: 'jason'}].some(el => el.name === 'trent')
Array.includes compares by object identity just like obj === obj2, so sadly this doesn't work unless the two items are references to the same object. You can often use Array.prototype.some() instead which takes a function:
const arr = [{a: 'b'}]
console.log(arr.some(item => item.a === 'b'))
But of course you then need to write a small function that defines what you mean by equality.
Its' because both of the objects are not the same. Both are stored at different place in memory and the equality operation results false.
But if you search for the same object, then it will return true.

Also, have a look at the below code, where you can understand that two identical objects also results false with the === operator.
For two objects to return true in ===, they should be pointing to same memory location.

Usesome method to check whether Capulet exists in an array:
let obj = { last: "Capulet" };
const isExist = whatIsInAName.some(f => f.last == obj.last)
const whatIsInAName = [
{ first: "Romeo", last: "Montague" },
{ first: "Mercutio", last: null },
{ first: "Tybalt", last: "Capulet" }
];
let obj = { last: "Capulet" };
const isExist = whatIsInAName.some(f => f.last == obj.last)
console.log(`Exists: ${isExist}`)
Or you can use filter to get all objects based on criteria:
const whatIsInAName = [
{ first: "Romeo", last: "Montague" },
{ first: "Mercutio", last: null },
{ first: "Tybalt", last: "Capulet" }
];
let obj = { last: "Capulet" };
const result = whatIsInAName.filter(f => f.last == obj.last);
console.log(result)
actually you can do a custom includes using some which will be faster than a map/filter
function whatIsInAName(arr, obj) {
return arr.some(({
last
}) => last === obj.last)
}
const testArray = [{
first: "Romeo",
last: "Montague"
},
{
first: "Mercutio",
last: null
},
{
first: "Tybalt",
last: "Capulet"
}
]
const testObj1 = {
last: "Capulet"
}
const testObj2 = {
last: "FOO"
}
const res1 = whatIsInAName(testArray, testObj1);
const res2 = whatIsInAName(testArray, testObj2);
console.log(res1);
console.log(res2);
You can turn the values of an Object into an array and test that a string is present. It assumes that the Object is not nested and the string is an exact match:
var obj = { a: 'test1', b: 'test2' };
if (Object.values(obj).indexOf('test1') > -1) {
console.log('has test1');
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values
Shortest ES6+ one liner:
let exists = Object.values(obj).includes("test1");
Hei, just published chai-subset. Check this out: https://www.npmjs.org/package/chai-subset This should work for you)
var chai = require('chai');
var chaiSubset = require('chai-subset');
chai.use(chaiSubset);
var obj = {
a: 'b',
c: 'd',
e: {
foo: 'bar',
baz: {
qux: 'quux'
}
}
};
expect(obj).to.containSubset({
e: {
foo: 'bar',
baz: {
qux: 'quux'
}
}
});
The include and contain assertions can be used as either property based language chains or as methods to assert the inclusion of an object in an array or a substring in a string. When used as language chains, they toggle the contain flag for the keys assertion. [emphasis mine]
So if you're invoking include on an object (not an array or a string), then it only serves to toggle the contain flag for the keys assertion. By the looks of your example, testing for deep equality would make more sense, possibly checking for the key first.
origins.should.include.keys("otherObj");
origins.otherObj.should.deep.equal(match.otherObj);
Actually, now I browse the other examples, you would probably be happiest with this :
origins.should.have.deep.property("otherObj", match.otherObj)
does include works with array of objects?
Yes — if you use the same object as the argument to includes that's in the array:
const obj = {name: "Dan", id: 2};
const arr = [{name: "T.J.", id: 42}, obj, {name: "Joe", id: 3}];
console.log(arr.includes(obj)); // true
console.log(arr.includes({name: "Dan", id: 2})); // false
includes uses a === check, and o1 === o2 is only ever true when o1 and o2 refer to the same object. In your example, you're using two different but equivalent objects instead.
For your use case, you probably want some, which lets you execute a callback to determine whether an entry in the array matches a condition:
if (arr.some(e => e.id === 2)) {
Example:
const obj = {name: "Dan", id: 2};
const arr = [{name: "T.J.", id: 42}, obj, {name: "Joe", id: 3}];
console.log(arr.some(obj => obj.id === 2)); // true
There are various ways to spin that, depending on what you want the check to be (which are discussed at length in this question's answers), but that just means adjusting the contents of the function you pass some.
Not like that. Use some instead:
arr.some(obj => obj.id === 2)
Which checks if there is an object with id equals to 2.
If you are checking for both id and name then:
arr.some(obj => obj.id === 2 && obj.name === "Dan")