Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ES6 Set allows duplicate array/object

Please have a look at the below script. I am testing it with Chrome.

/*declare a new set*/
var items = new Set()

/*add an array by declaring as array type*/
var arr = [1,2,3,4];
items.add(arr);

/*print items*/
console.log(items); // Set {[1, 2, 3, 4]}

/*add an array directly as argument*/
items.add([5,6,7,8]);

/*print items*/
console.log(items); // Set {[1, 2, 3, 4], [5, 6, 7, 8]}

/*print type of items stored in Set*/
for (let item of items) console.log(typeof item); //object, object

/*check if item has array we declared as array type*/
console.log(items.has(arr)); // true

/*Now, check if item has array we added through arguments*/
console.log(items.has([5,6,7,8])); //false

/*Now, add same array again via argument*/
items.add([1,2,3,4]);

/*Set has duplicate items*/
console.log(items); // Set {[1, 2, 3, 4], [5, 6, 7, 8], [1, 2, 3, 4]}
  1. Why it is returning false at items.has([5,6,7,8])?
  2. Why it is allowing duplicate values? I thought "A set is in an ordered list of values that cannot contain duplicates"
  3. How to access array added by items.add([5,6,7,8])?
like image 399
jeetaz Avatar asked Apr 13 '16 04:04

jeetaz


3 Answers

  1. Why it is returning false at items.has([5,6,7,8])?

    From MDN

    The Set object lets you store unique values of any type, whether primitive values or object references.

    The objects are compared using the reference, not the value. Sets uses SameValueZero(x, y) comparison algorithm to compare values. It says Return true if x and y are the same Object value. Otherwise, return false.

  2. Why it is allowing duplicate values? I thought "A set is in an ordered list of values that cannot contain duplicates"

    Same as #1. An non-primitive value is said to be already exists in set if the same object(not just same looking) already added in the set.

  3. How to access array added by items.add([5,6,7,8])?

    You've to create a variable and add the variable to the set. Then this variable can be used to check if set has that array or not.

like image 195
Tushar Avatar answered Oct 21 '22 02:10

Tushar


Quoting the specification:

Set objects are collections of ECMAScript language values. A distinct value may only occur once as an element of a Set’s collection. Distinct values are discriminated using the SameValueZero comparison algorithm.

(emphasis mine)

The SameValueZero comparison algorithm handles any two arguments of the same type (where that type isn't null, undefined, a string, number, boolean, or Symbol) as follows:

Return true if x and y are the same Object value. Otherwise, return false.

Ultimately, what this means is that the objects are compared by reference (that is, effectively, "do these two objects point to the same location in memory?") Each time you create an array using either brackets ([]) or constructor invocation (new Array()) you create a new instance of Array in memory. When you keep a reference to the array, it will match (e. g. arr === arr). When you create new instances and compare them they will not match, even though their contents would compare as equal (e. g. [1, 2, 3] !== [1, 2, 3]).

like image 26
Sean Vieira Avatar answered Oct 21 '22 02:10

Sean Vieira


  1. Array comparision does not compare values it compares references so it is returning false. [1] === [1] will return false always.
  2. See reference MDN

The Set object lets you store unique values of any type, whether primitive values or object references.

you are passing new object not reference so it is allowing to add duplicate. which is actually visually similar but reference are different.

  1. Pass reference by assigning it to variable to access the added array.
like image 35
murli2308 Avatar answered Oct 21 '22 01:10

murli2308