今天有个朋友有一个需求,是要随机几个随机数,但是还不能有重复。
就简单的写了一个,根据指定范围生成N个随机数,不会重复。
同时呢,考虑会有从一个数组中取出多个不重复成员的需求,也一并写了出来
代码还是挺简单的,主要思路是生成指定范围内的所有数值;
然后随机从数组里面抽取一个成员,然后删除这个成员。以免下次重复抽取。
/**
* 产生指定范围不重复的随机数
* 参数一: 最小值 int
* 参数二: 最大值 int
* 参数三: 随机数量 int
* 返回值: 结果数组 Array
**/
function getRandNumForRange(least, max, num) {
// 检查传值是否合法
if(num > max - least) return false;
// 产生指定范围的所有数值
var numList = [], numRandList = [], randId;
for (var i = least; i < max; i++) numList.push(i);
// 产生记录次数
for (var i = 0; i < num; i++) {
randId = Math.floor(Math.random() * numList.length); // 随机一个数组ID
numRandList.push(numList[randId]); // 获取这个值
numList.splice(randId, 1); // 删除这个成员 防止下次再次生成
}
return numRandList;
}
/**
* 产生指定数组不重复的随机数
* 参数一: 抽取数组 Array
* 参数二: 随机数量 int
* 返回值: 结果数组 Array
**/
function getRandNumForArray(numArray, num) {
// 检查传值是否合法
if(num > numArray.length) return false;
// 产生记录次数
var numRandList = [], randId;
for (var i = 0; i < num; i++) {
randId = Math.floor(Math.random() * numArray.length); // 随机一个数组ID
numRandList.push(numArray[randId]); // 获取这个值
numArray.splice(randId, 1); // 删除这个成员 防止下次再次生成
}
return numRandList;
}
上面的代码写完以后,又琢磨了半天,感觉还有 效率更高的方法,改造一下,新代码出炉
新代码思路是:产生指定范围内的数字数组,然后对他进行随机排序,然后取出前几个成员。
同样不会有重复,而且,效率会比原来的方法更高一点。
/**
* 产生指定范围不重复的随机数(对数组随机排序思路)
* 参数一: 最小值 int
* 参数二: 最大值 int
* 参数三: 随机数量 int
* 返回值: 结果数组 Array
**/
function getRandNumForRangeN(least, max, num) {
// 检查传值是否合法
if(num > max - least) return false;
// 产生指定范围的所有数值
var numList = [];
for (var i = least; i < max; i++) numList.push(i);
// 对数组随机排序
numList.sort(function() { return Math.random() < 0.5 ? -1 : 1 });
// 返回前N个值
return numList.slice(0, num);
}
/**
* 产生指定数组不重复的随机数(对数组随机排序思路)
* 参数一: 抽取数组 Array
* 参数二: 随机数量 int
* 返回值: 结果数组 Array
**/
function getRandNumForArrayN(numArray, num) {
// 检查传值是否合法
if(num > numArray.length) return false;
// 对数组随机排序
numArray.sort(function() { return Math.random() < 0.5 ? -1 : 1 });
// 返回前N个值
return numArray.slice(0, num);
}
效率演示: