0

I'm trying to come up with a solution to a uniqueness problem in a program I'm writing using Sets and the has() method, but I'm running into the following problem. It seems like has() behaves differently based on if I build the variable inside the has() call (first code example, which returns false) versus if I initialize the variable before hand and pass it in (second example, which returns true).

I was hoping someone could shed some light on what's going on here as I don't want to introduce a bug into our code base.

const set1 = new Set([
  {loc:"hello", x:1, y:2}, 
  {loc:"Goodbye", x:1, y:2}
]);

console.log(set1.has(
  {loc:"hello", x:1, y:2}
));
//outputs False
const elem = {loc:"hello", x:1, y:2};
const set1 = new Set([
  elem, 
  {loc:"Goodbye", x:1, y:2}
]);

console.log(set1.has(
  elem
));
//outputs True
Michael Hackman
  • 491
  • 2
  • 6
  • 21
  • 1
    `({loc:"hello", x:1, y:2} !== {loc:"hello", x:1, y:2})` – ASDFGerte Oct 26 '19 at 16:31
  • https://stackoverflow.com/questions/38962174/set-prototype-has-with-predicate , https://stackoverflow.com/questions/38964533/checking-if-a-set-contains-a-list-in-javascript , https://stackoverflow.com/questions/36588890/es6-set-allows-duplicate-array-object , https://stackoverflow.com/questions/51293422/does-js-set-has-method-do-shallow-checks , ... – ASDFGerte Oct 26 '19 at 16:36

1 Answers1

0

It specifically nothing has to do with has method, this is how the objects are compared in JS.

1st one fails because the value you set and value you're checking are two separate references and in JS two references can never be equal

2nd snippet yield true as the value you set and trying to check both are same reference so it result in true

let obj = {a:'a'}

console.log(obj === obj)
console.log(obj === {a:'a'})
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
  • That's good to know. So do you know how I could use a Set that stores objects in the way I'm attempting to do above? Or do I just do it myself and loop through an array checking each object against each other – Michael Hackman Oct 26 '19 at 16:34
  • @MichaelHackman no you can't do it with the Set like this, i am not getting exactly what you're trying to achieve with such structure, if you need to compare value with just sinle property then you can use `Map`, if you want to match all the keys and values you need to do it manually, or you can use `_isEqual` or such sort of functions available in library like loadash, underscroe etc. – Code Maniac Oct 26 '19 at 16:40
  • If you want to check equality of objects I would recommend you to use `_.isEqual(object1, object2);` from [underscorejs](https://underscorejs.org/) or [lodash](https://lodash.com/) – Tibike Oct 26 '19 at 16:43