I have the following javascript code:
const theJvScSet = new Set()
while (theJvScSet.size != 10) {
let iniKick = Math.floor(Math.random()*2), setElement = [iniKick]
for (let index = 0; index < 2; index ) {
const spinVal = 1 Math.floor(Math.random()*5)
setElement.push(spinVal)
}
theJvScSet.add(setElement)
}
And after execution I find myself with twice the value : [0, 3, 5] in the set. How is this possible? I expected the line of code:
theJvScSet.add(setElement)
to only insert in the set values not already in there.
What do I need to change to make sure only different values will be accepted inside theJvScSet?
CodePudding user response:
An array is in Immutable object that reference a part of memory. you can easily test that with the following:
the Set does not store equal values. in this case, the two arrays are different immutable objects.
CodePudding user response:
JavaScript will do "reference equality" checking, meaning that it checks, for any two objects in the set, whether a === b
, or that a
and b
point to the same address in memory.
Because these are two different arrays stored in two different parts of memory, they are not equal by reference.
You could fix this by iterating through the array, doing a JSON.stringify
on each element to bring them all into String objects for comparison, and then remove duplicates and do JSON.parse
.
CodePudding user response:
If you want to have only differents values you can store your arrays in an array and after each iteration verify before if the array doesn’t already include the new value :
const theJvScSet = []
while (theJvScSet.size != 10) {
let iniKick = Math.floor(Math.random()*2), setElement = [iniKick]
for (let index = 0; index < 2; index ) {
const spinVal = 1 Math.floor(Math.random()*5)
setElement.push(spinVal)
}
if (theJvScSet.findIndex(arr => arr.every((n, i) => setElement[i] === n)) === -1)
theJvScSet.add(setElement)
}
CodePudding user response:
In JavaScript each separately initialised array is considered to be "different" and can therefore be added to a set. If you try to add a reference to the same array multiple times, it will appear only once:
const arr=[4,5,6], unique=new Set();
unique.add([1,2,3]);
unique.add([1,2,3]);
unique.add([1,2,3]);
unique.add(arr);
unique.add(arr);
unique.add(arr);
console.log([...unique]);
If you want to get a non-repeating sequence of array values you should instead generate an array of all possible (2*5*5=50) values at first, shuffle the array and then slice off the first 10 values.
function shfl(a){ // Durstenfeld shuffle (similar to Fisher-Yates)
for(let j,i=a.length;i>1;){
j=Math.floor(Math.random()*i--);
if (i!=j) [a[i],a[j]]=[a[j],a[i]]
}
return a
}
function mkArr(base,n){
return Array(n).fill(0).map((_,i)=>base i)
}
const all=[];
mkArr(0,2).forEach(i=>
mkArr(1,5).forEach(j=>
mkArr(1,5).forEach(k=>
all.push([i,j,k]))));
console.log(shfl(all).slice(0,10))