1

I have this code:

const arr = [
{name:"Bill", age:11},
{name:"Bill", age:11}
]
console.log(arr.includes({name:"Bill", age:11}))

Here i want to check if the array includes {name:"Bill", age:11}.
Why i get false? And how to make this checking using includes?

Liam
  • 27,717
  • 28
  • 128
  • 190
Asking
  • 3,487
  • 11
  • 51
  • 106
  • you compare an object with other objects. they have all different object references. – Nina Scholz Aug 10 '20 at 08:10
  • It can help [How to determine equality for two JavaScript objects?](https://stackoverflow.com/questions/201183/how-to-determine-equality-for-two-javascript-objects) – Nikita Madeev Aug 10 '20 at 08:11
  • [Object comparison in JavaScript](https://stackoverflow.com/questions/1068834/object-comparison-in-javascript) – DBS Aug 10 '20 at 08:11
  • @NinaScholz, what could be the solution? Could you show please? – Asking Aug 10 '20 at 08:11
  • There is no built-in way to check equality on objects, because the comparison is done by reference (two objects can have different references even if they have the same contents). I suggest you either do the comparison key by key, or use a library method like [`_.isEqual()`](https://lodash.com/docs/4.17.15#isEqual). – M0nst3R Aug 10 '20 at 08:15
  • `arr.some(v => JSON.stringify(v) === JSON.stringify({name: "Bill", age: "11"}));` – Scriptkiddy1337 Aug 10 '20 at 08:16

2 Answers2

8

The includes() method compares objects by reference and not by value. In your case the three objects have three different references although they have the same properties and the same values in them.

const bill = { name: 'Bill', age: 11 }
const arr = [bill, { name: 'Jane', age: 18 }]

arr.includes(bill) // true (same reference)
arr.includes({ name: 'Bill', age: 11 }) // false (different reference)

If you want to find objects by value, you can use the find() method and pass a filter function which checks if each property of the object matches your criteria.

const arr = [{name:"Bill", age:11}, {name:"Jane", age:18}]
const exists = Boolean(arr.find(x => x.name === 'Bill' && x.age === 11))

// or even simpler using the `some()` method
const exists = arr.some(x => x.name === 'Bill' && x.age === 11)
Tsvetan Ganev
  • 8,246
  • 4
  • 26
  • 43
  • 2
    An alternative to combining `Boolean()` and `Array.find()` is simply using [`Array.some()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some). – M0nst3R Aug 10 '20 at 08:18
  • 1
    Thanks for reminding me about this method. I've added it to the examples. – Tsvetan Ganev Aug 10 '20 at 09:26
2

You can create a custom array prototype method for this like includesObj

const arr = [
{name:"Bill", age:11},
{name:"Bill", age:11}
]

Array.prototype.includesObj = function(obj) {
   for(let i = 0; i < this.length; i++) {
      if(JSON.stringify(this[i], Object.keys(this[i]).sort()) === JSON.stringify(obj, Object.keys(obj).sort())) return true;
   }
   return false;
}

console.log(arr.includesObj({name: "Bill", age: 11}))
console.log(arr.includesObj({age: 11, name: "Bill"}))
console.log(arr.includesObj({name: "Bob", age: 11}))
bill.gates
  • 14,145
  • 3
  • 19
  • 47