Javascript 从数组中获取随机元素将返回相同的元素

Javascript 从数组中获取随机元素将返回相同的元素,javascript,jquery,random,Javascript,Jquery,Random,请参考下面的代码 for (var i = 0; i < elements.length; i++) { //var element = elements[Math.floor(Math.random()*elements.length)]; this.animateSymbol(elements[Math.floor(Math.random()*elements.length)]); } for(var i=0;i=0和

请参考下面的代码

for (var i = 0; i < elements.length; i++) 
{
     //var element = elements[Math.floor(Math.random()*elements.length)];
     this.animateSymbol(elements[Math.floor(Math.random()*elements.length)]);
}
for(var i=0;i
元素数组包含svg元素列表(圆/路径/椭圆等)。我想从元素数组中选择随机元素

它返回相同的元素在某些情况下,我想随机选择元素,无需再次选择相同的元素。需要从该数组中选择不同的元素

有什么问题吗?为什么它返回相同的索引和相同的元素

谢谢


湿婆

随机数是随机的。不能保证你不会得到相同的随机数两次。事实上,当你把随机数转换成有限范围的整数时,很可能会得到两次相同的数

您可以通过复制数组来修复此问题,然后每次从数组中获取值时,将其删除。让我们把生成随机索引的代码分解成一个单独的函数;在其他情况下也很方便:

// Return a random integer >= 0 and < n
function randomInt( n ) {
    return Math.floor( Math.random() * n );
}

var copy = elements.slice();
while( copy.length ) {
    var index = randomInt( copy.length );
    this.animateSymbol( copy[index] );
    copy.splice( index, 1 );
}
任何一个都做同样的事情。为了清晰起见,我有点喜欢分步执行的方法,但是
.splice()
方法返回您删除的元素数组非常方便

以下是您可以粘贴到JavaScript控制台进行测试的代码版本:

// Return a random integer >= 0 and < n
function randomInt( n ) {
    return Math.floor( Math.random() * n );
}

var elements = [ 'a', 'b', 'c', 'd', 'e' ];
var copy = elements.slice();
while( copy.length ) {
    var index = randomInt( copy.length );
    console.log( copy.splice( index, 1 )[0] );
}
console.log( 'Done' );
//返回一个随机整数>=0和

它也值得一看。它使用Fisher-Yates随机洗牌,将数组随机化。这对于非常长的数组可能更有效。

这是因为您使用的是
随机
无法保证相同的数字不会重复

在您的情况下,我建议您使用某种洗牌来创建一个随机顺序数组


您可以找到这样的方法

所以每次都需要一个随机元素?但同一元素不能重复两次

试试这个:

for (var i = 0; i < elements.length; i++) {
     //var element = elements[Math.floor(Math.random()*elements.length)];
     var index = Math.floor(Math.random()*elements.length);         
     this.animateSymbol(elements[index]);   
     elements.splice(index, 1);
}
for(var i=0;i

一旦选定该项,这将从数组中删除该项

尝试捕获生成的随机数,并检查是否不再使用它们

以下是我为此创建的快速对象:

function PersistentRandom(exclusiveUpperBounds){
  this.spent = [];
  this.bounds = exclusiveUpperBounds;
}

PersistentRandom.prototype.getValue = function(){
    if(this.spent.length != this.bounds -1){
        var tmp = Math.floor(Math.random()* this.bounds);
        if(this.spent.indexOf(tmp) == -1){
            this.spent.push(tmp);
            return tmp;
        }else{
            return this.getValue();
        }
    }else{
        //If all numbers are used reset and start again
        this.spent = [];
        return this.getValue();
    }
};

//Usage
var pr = new PersistentRandom(11);

var x = 0;
while(x < 15){
   console.log(pr.getValue());
   x++;
}
函数PersistentRandom(exclusiveUpperBounds){
this.persed=[];
this.bounds=排他性UpperBounds;
}
PersistentRandom.prototype.getValue=函数(){
if(this.spend.length!=this.bounds-1){
var tmp=Math.floor(Math.random()*this.bounds);
if(this.spend.indexOf(tmp)=-1){
这个.dust.push(tmp);
返回tmp;
}否则{
返回这个.getValue();
}
}否则{
//如果使用了所有号码,请重置并重新启动
this.persed=[];
返回这个.getValue();
}
};
//用法
var pr=新的持久性分布(11);
var x=0;
而(x<15){
console.log(pr.getValue());
x++;
}

工作示例

所以你想要的就像一副牌,你洗牌,然后一张接一张,因此它们永远不会重复

对于你的问题,我会使用下面的方法,使用标准的洗牌

函数洗牌(obj){
var i=对象长度;
var rnd,tmp;
而(i){
rnd=Math.floor(Math.random()*i);
i-=1;
tmp=obj[i];
obj[i]=obj[rnd];
obj[rnd]=tmp;
}
返回obj;
}
var元素=[0,1,2,3,4,5,6,7,8,9];
var随机化=elements.slice();
随机分组;
随机。forEach(函数(元素){
控制台日志(元素);

});没有说明随机数不能与前一个随机数相同。您确定元素包含多个元素吗?做一个console.log(elements.length)。谢谢你的回复。但我已经在控制台窗口中进行了检查,相同的随机数将打印在该窗口中。为什么?@SivaRajini-不知道你指的是什么。我添加了一个可以粘贴到JavaScript控制台的代码版本。它似乎工作正常。我是否可以在for循环中使用您的代码(var i=0;i@michael既然您正在从数组中删除each元素,它是否会影响for循环?不,此代码中已经有了循环。您不需要在它周围再加一个循环。将最后一个示例按原样粘贴到JavaScript控制台中,看看它是如何工作的。+1对于shuffle,这也是我对所述问题的解释。-1,这不起作用,因为每次从数组中删除元素时,元素数组长度都会变短。解决方案是反转for循环,使其向下计数。+1对于其他解决方案,可以设置“this.spend.length=0;”,而不是“this.spend=[]´作为一种改进,但比移除元素的建议要好,尽管有点过于复杂,我感觉并依赖于Array.indexOf(虽然有垫片)。此解决方案的好处是重置并重新启动。
function PersistentRandom(exclusiveUpperBounds){
  this.spent = [];
  this.bounds = exclusiveUpperBounds;
}

PersistentRandom.prototype.getValue = function(){
    if(this.spent.length != this.bounds -1){
        var tmp = Math.floor(Math.random()* this.bounds);
        if(this.spent.indexOf(tmp) == -1){
            this.spent.push(tmp);
            return tmp;
        }else{
            return this.getValue();
        }
    }else{
        //If all numbers are used reset and start again
        this.spent = [];
        return this.getValue();
    }
};

//Usage
var pr = new PersistentRandom(11);

var x = 0;
while(x < 15){
   console.log(pr.getValue());
   x++;
}