似乎找不到答案,假设我有这个:
setInterval(function() {
m = Math.floor(Math.random()*7);
$('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);
如何使随机数不重复。例如,如果随机数是 2,我不希望再次出现 2。
有多种方法可以实现这一目标。
解决方案A: 如果数字范围不大(假设小于 10),您可以只跟踪已经生成的数字。然后,如果生成重复的数字,请将其丢弃并生成另一个数字。
解决方案B: 预先生成随机数,将它们存储到数组中,然后遍历该数组。您可以通过获取数字
1,2,...,n
然后将它们洗牌来完成此操作。
shuffle = function(o) {
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
var randorder = shuffle([0,1,2,3,4,5,6]);
var index = 0;
setInterval(function() {
$('.foo:nth-of-type('+(randorder[index++])+')').fadeIn(300);
}, 300);
解决方案C: 跟踪数组中可用的数字。随机选择一个数字。从所述数组中删除数字。
var randnums = [0,1,2,3,4,5,6];
setInterval(function() {
var m = Math.floor(Math.random()*randnums.length);
$('.foo:nth-of-type('+(randnums[m])+')').fadeIn(300);
randnums = randnums.splice(m,1);
}, 300);
您似乎想要一个从 0 到 6 的不重复随机数,与 tskuzzy 的答案类似:
var getRand = (function() {
var nums = [0, 1, 2, 3, 4, 5, 6];
var current = [];
function rand(n) {
return (Math.random() * n) | 0;
}
return function() {
if (!current.length) current = nums.slice();
return current.splice(rand(current.length), 1)[0];
}
}());
// Run 3 times
for (let i=0; i<3; i++) {
console.log('run ' + i);
for (let j=0; j<7; j++) {
console.log(getRand());
}
}
它将按随机顺序返回数字 0 到 6。每抽完一次,就会重新开始。
你能尝试一下吗
setInterval(function() {
m = Math.floor(Math.random()*7);
$('.foo:nth-of-type(' + m + ')').fadeIn(300);
}, 300);
我喜欢尼尔的回答,尽管这是需要一些递归。 这里是用java编写的,你仍然会得到大概的想法。 请注意,如果您提取的数字多于 MAX,您将陷入无限循环,我可以修复该问题,但为了清楚起见,将其保留原样。
编辑:看到尼尔添加了一个 while 循环,这样效果很好。
public class RandCheck {
private List<Integer> numbers;
private Random rand;
private int MAX = 100;
public RandCheck(){
numbers = new ArrayList<Integer>();
rand = new Random();
}
public int getRandomNum(){
return getRandomNumRecursive(getRand());
}
private int getRandomNumRecursive(int num){
if(numbers.contains(num)){
return getRandomNumRecursive(getRand());
} else {
return num;
}
}
private int getRand(){
return rand.nextInt(MAX);
}
public static void main(String[] args){
RandCheck randCheck = new RandCheck();
for(int i = 0; i < 100; i++){
System.out.println(randCheck.getRandomNum());
}
}
}
通常我的方法是创建一个包含所有可能值的数组,然后:
生成的数字集将包含所有索引,不重复。
更好的是,也许是这样的:
var numArray = [0,1,2,3,4,5,6];
numArray.shuffle();
然后只需浏览这些项目,因为随机播放会将它们随机化并一次将它们弹出。
这是一个简单的修复,虽然有点初级:
if(nextNum == lastNum){
if (nextNum == 0){nextNum = 7;}
else {nextNum = nextNum-1;}
}
如果下一个数字与上一个数字相同,只需减 1,除非该数字为 0(零),并将其设置为集合中的任何其他数字(我选择 7,最高索引)。
我在循环函数中使用了这个方法,因为选择数字的唯一规定是不能与最后一个相同。
不是最优雅或技术上最有天赋的解决方案,但它有效:)
使用套装。它们在 ES6 中被引入到规范中。集合是一种数据结构,表示唯一值的集合,因此“它不能包含任何重复值”。 我需要 6 个随机的、不可重复的数字,范围从 1 到 49。我首先创建一个大约 30 位的较长集合(如果值重复,该集合将包含更少的元素),将集合转换为数组,然后将其前 6 个元素切片。简单易行。 Set.length 默认情况下是 undefined 并且它没有用,这就是为什么如果您需要特定长度,将其转换为数组会更容易。
let randomSet = new Set();
for (let index = 0; index < 30; index++) {
randomSet.add(Math.floor(Math.random() * 49) + 1)
};
let randomSetToArray = Array.from(randomSet).slice(0,6);
console.log(randomSet);
console.log(randomSetToArray);
function randomNumber(max) {
return Math.floor(Math.random() * max + 1);
}
const list = []
while(list.length < 10 ){
let nbr = randomNumber(500)
if(!list.find(el => el === nbr)) list.push(nbr)
}
console.log("list",list)
var RecordKeeper = {};
SRandom = function () {
currTimeStamp = new Date().getTime();
if (RecordKeeper.hasOwnProperty(currTimeStamp)) {
RecordKeeper[currTimeStamp] = RecordKeeper[currTimeStamp] + 1;
return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
}
else {
RecordKeeper[currTimeStamp] = 1;
return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
}
}
这使用时间戳(每毫秒)来始终生成唯一的数字。
function in_array(needle, haystack)
{
for(var key in haystack)
{
if(needle === haystack[key])
{
return true;
}
}
return false;
}
(函数来自:javascript function inArray
var done = [];
setInterval(function() {
var m = null;
while(m == null || in_array(m, done)){
m = Math.floor(Math.random()*7);
}
done.push(m);
$('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);
此代码在获取所有七个数字后将被卡住,因此您需要在找到所有数字后确保它存在。