JavaScript中Set存储数组出现重复元素的问题及解决方法
问题根源
JavaScript里的Set是靠引用地址判断元素是否重复的,不是看内容。你每次循环生成的setElement都是新的数组对象——哪怕两个数组内容全一样,比如都是[0,3,5],它们在内存里的地址也不一样,Set就会把它们当成不同的元素,自然会重复添加。
修改方案
有两种实用的解决办法:
方案1:将数组转为字符串存入Set
把数组转成唯一对应的字符串(用JSON.stringify就行),这样内容相同的数组会被转成完全一样的字符串,Set就能正确去重。之后如果需要数组格式,再用JSON.parse转回来:
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) } // 转成字符串存入Set theJvScSet.add(JSON.stringify(setElement)) } // 如需转回数组格式 const uniqueArrays = Array.from(theJvScSet).map(str => JSON.parse(str))
方案2:添加前手动检查数组内容
如果不想转字符串,可以在添加到Set前,遍历现有元素对比数组内容是否一致。这种方法更直观,但当Set里元素较多时,性能会比字符串方案差一些:
const theJvScSet = new Set() // 辅助函数:判断两个数组内容是否完全一致 function arraysEqual(arr1, arr2) { if (arr1.length !== arr2.length) return false for (let i = 0; i < arr1.length; i++) { if (arr1[i] !== arr2[i]) return false } return true } 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) } // 检查是否已有相同内容的数组 let exists = false for (const item of theJvScSet) { if (arraysEqual(item, setElement)) { exists = true break } } if (!exists) { theJvScSet.add(setElement) } }
内容的提问来源于stack exchange,提问作者Michel
相关产品推荐
相关产品推荐

