JS如何生成number属性值互不重复的随机对象数组?
问题原因
原代码每次调用Math.random()生成数字时,都是独立在0-9区间取值,没有做重复值校验,自然会出现number属性重复的情况。
要得到10个number值完全不重复、且取值刚好覆盖0-9的对象数组,最高效的方案不是反复随机碰运气,而是先生成0-9的全量数字数组,随机打乱顺序后再映射成目标结构,从根源上避免重复。
可行实现
这里用经典的Fisher-Yates洗牌算法做打乱,时间复杂度O(n),随机性有保证,不会出现重复值:
// 1. 先生成0-9的连续整数数组,所有数字天然唯一 const numPool = Array.from({ length: 10 }, (_, index) => index); // 2. 从后往前遍历,随机交换位置完成洗牌 for (let i = numPool.length - 1; i > 0; i--) { const randomPos = Math.floor(Math.random() * (i + 1)); [numPool[i], numPool[randomPos]] = [numPool[randomPos], numPool[i]]; } // 3. 把打乱后的数字映射成要求的对象结构 const newArray = numPool.map(number => ({ number, display: false }));
如果想要更精简的链式写法,也可以参考下面的实现,逻辑和上面完全一致:
const newArray = Array.from({ length: 10 }, (_, i) => i) .sort(() => Math.random() - 0.5) .map(number => ({ number, display: false }));
注意:
sort(() => Math.random() - 0.5)的写法虽然简短,但实际打乱的随机性不如Fisher-Yates算法,对随机性要求高的场景优先选前面的经典洗牌实现。
不推荐的方案
不要用「每次生成随机数后检查是否已存在,存在就重新生成」的逻辑:当已生成的数字越来越多时,随机到重复值的概率会持续升高,极端场景下会出现多次循环重试才能凑齐10个数字的问题,性能差还存在理论上的死循环可能。
内容的提问来源于stack exchange,提问作者jsancho
相关产品推荐
相关产品推荐

