下面的方法在 [min, max] 范围内生成一个新的随机数,并确保这个数字与前一个不同,没有循环和递归调用(Math.random()
只调用一次):
- 如果存在先前的数字,则将 max 减一
- 在范围内生成一个新的随机数
- 如果新数等于或大于前一个,则加一个
(另一种选择:如果新数等于前一个,则将其设置为 max + 1)
为了在闭包中保留之前的数字,getNumber
可以在 IIFE 中创建:
// getNumber generates a different random number in the inclusive range [0, 4]
var getNumber = (function() {
var previous = NaN;
return function() {
var min = 0;
var max = 4 + (!isNaN(previous) ? -1 : 0);
var value = Math.floor(Math.random() * (max - min + 1)) + min;
if (value >= previous) {
value += 1;
}
previous = value;
return value;
};
})();
// Test: generate 100 numbers
for (var i = 0; i < 100; i++) {
console.log(getNumber());
}
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
在[MIN,MAX]范围是由包括通过加入1至max - min
在下面的语句:
var value = Math.floor(Math.random() * (max - min + 1)) + min;
这不是问题中的要求,但我觉得使用包含范围更自然。