JavaScript数组处理bug:随机数索引导致重复ID问题求助
问题分析:随机生成ID重复的原因及修复方案
哦,我一眼就发现问题出在哪了——你把数组的索引和对象的id属性完全搞混啦!
为什么会出现重复ID?
你的判断条件是if (!coll_[random_number]),但你生成的random_number是1、2、3(因为Math.floor((Math.random()*3)+1)的结果范围是1-3),而数组的索引是从0开始的:
- 第一次生成random_number=1时,
coll_[1]是undefined(此时数组是空的,连索引0都没有元素),所以你执行push,把id=1的对象加到了数组的索引0位置。 - 下次再生成random_number=1时,
coll_[1]依然是undefined(因为此时数组长度为1,最大索引是0,索引1根本不存在),于是你又执行了push,又加了一个id=1的对象到数组的索引1位置——这就造成了重复的id!
你原本想判断“数组里有没有id等于random_number的对象”,但实际写的是“数组的random_number索引位置有没有元素”,这完全是两回事。
修复方案
这里给你两种靠谱的解决办法:
方案1:用findIndex精准查找对象
直接根据对象的id属性去数组里查找,判断是否存在:
var coll_ = []; // 用let声明循环变量,避免全局污染 for (let i = 0; i < 30; i++) { const random_number = Math.floor((Math.random() * 3) + 1); // 查找数组中id匹配的对象索引 const existingItemIndex = coll_.findIndex(item => item.id === random_number); if (existingItemIndex === -1) { // 不存在则添加新对象 coll_.push({ id: random_number, min: 0, max: 1 }); } else { // 存在则更新max值 coll_[existingItemIndex].max++; } } document.write(JSON.stringify(coll_));
方案2:用对象做映射(性能更优)
如果后续数据量变大,每次用findIndex遍历数组效率会降低,推荐用对象来做id到对象的映射,天然保证id唯一性,最后再转成数组:
// 用对象存储id对应的对象 const idMap = {}; for (let i = 0; i < 30; i++) { const random_number = Math.floor((Math.random() * 3) + 1); if (!idMap[random_number]) { idMap[random_number] = { id: random_number, min: 0, max: 1 }; } else { idMap[random_number].max++; } } // 把对象的值转为数组 const coll_ = Object.values(idMap); document.write(JSON.stringify(coll_));
额外小提醒
- 尽量用
const/let声明变量,避免像原来的i、random_number那样变成全局变量,容易引发其他问题; - 访问对象属性时,
coll_[existingIndex].max比coll_[existingIndex]['max']更简洁哦。
内容的提问来源于stack exchange,提问作者Mars




