2011-08-20 88 views
7

因此,我试图从数组中选择一个随机条目,然后使其成为特定条目,直到每个条目都被选中为止。 基本上,我不想看到任何相同的条目,直到数组中的所有条目都被选中。无需在JavaScript中选择两次的随机数组选择

因此,如果这是我的阵列...

keywords = 
[ 
"ppc", 
"games", 
"advertise", 
"meta", 
"home", 
"gaming", 
"welcome" 
] 
var keyword = keywords[Math.floor(Math.random()*keywords.length)] 
document.write(keyword); 

我不希望看到的输出:

meta, advertise, home, meta, gaming, welcome, ppc, welcome 

由于元选择了第二次之前曾入选过一次的一切。 我希望看到更多的东西一样。

meta, advertise, gaming,ppc, welcome, home, games, advertise, ppc, 

,因为这没有选择任何项目多次被随机选择的每一个条目之前(第二循环开始在第二个“广告”万一你没”但是正如你从上面发布的代码中可以看到的,我不知道如何做到这一点,我看到了一些例子,其中随机选择的条目实际上已经从数组中删除了完全但是这不是我想要做的,我只是希望每个条目都被选中一次,然后重新启动该流程。

有没有人知道这个代码?

+0

[阵列随机数]的可能重复(http://stackoverflow.com/questions/4373306/array-of-random-numbers) –

回答

0

如果您不介意更改数组,可以随机化数组中元素的顺序,然后将数组从第一个元素打印到最后。

OR

你可以使值1的另一个阵列对N(其中N是元件的数量)。随机化该数组的顺序,然后将其用作数组的索引,并从第一个到最后一个迭代它。

0

将您在散列中看到的数字(索引)存储在一个散列中,然后当您尝试查看一个新单词时,可以检查散列,如果您已经看到它,则生成一个新数字。确保检查散列长度是否与数组长度相同。

这可以避免更改数组。

+0

但是,假设你有1000个指数的阵列,概率找到独特的指数会随着每次迭代呈指数级增长。对于最后一次选择,您将有1/1000的机会结束该功能。所以循环会迭代1000次,甚至更多。添加索引时,这也成为更多问题。您的拣选功能可能需要数分钟才能结束。 – Krythic

+0

最好的解决方案是选择一个随机的指针,然后将该指针交换到所选数组的末尾,然后使用(array.Length - 1 - i)再次循环。您可以保证最佳的O/ñ。 – Krythic

5

这样做的一个非常简单的方法是每次选择一个随机元素时使用splice,并且一旦数组为空,则用原始值重新填充它。

例子:

(function() { 
    var arr = []; 

    window.getRandomThing = function() { 
     if (arr.length === 0) { 
      refill(); 
     } 

     return arr.splice(Math.random() * arr.length, 1)[0]; 
    }; 

    function refill() { 
     arr = [1,2,3,4,5]; 
    } 
}()); 
2

可以使原来的数组的副本,然后使用.splice()在随机指数抢值,从数组复制删除它。

因为副本每次只能减1,所以可以简单地做while(copy.length)

实施例:http://jsfiddle.net/fMXTF/

var keywords = [ 
"ppc", 
"games", 
"advertise", 
"meta", 
"home", 
"gaming", 
"welcome" 
]; 

var copy = keywords.slice(); 

while(copy.length) { 

    var keyword = copy.splice(Math.floor(Math.random()*copy.length), 1); 
    document.write(keyword + '<br>'); 

} 

注意,随机数是基于离copy.length,其中,由于.splice()的,由1在每次迭代中减少。因此它确保随机数始终基于副本的当前length

+0

这对我很好!谢谢。 – Abdel

7

您可以使用Array.sort()函数对其进行随机排序。

// random sort function 
function shuffle(a, b) 
{ 
    return Math.random() > 0.5 ? -1 : 1; 
} 

var keywords = ["ppc", "games", "advertise", "meta", "home", "gaming", "welcome"]; 

var randomKeywords = keywords.sort(shuffle); // new instance of a sorted randomly copy of the array 

alert(randomKeywords); 

更新:

洗牌更好的解决方案是使用Fisher-耶茨洗牌,如在本answer找到。

function shuffle(array) 
 
{ 
 
    var m = array.length, t, i; 
 
    while (m > 0) 
 
    { 
 
\t i = Math.floor(Math.random() * m--); 
 
\t t = array[m]; 
 
\t array[m] = array[i]; 
 
\t array[i] = t; 
 
    } 
 
    return array; 
 
} 
 

 
var keywords = ["ppc", "games", "advertise", "meta", "home", "gaming", "welcome"]; 
 

 
shuffle(keywords); // shuffles the array 
 

 
alert(keywords);

+0

这对Firefox和Opera在Linux上不起作用。我需要在'shuffle()'中取出'-1'。如果排序函数的'0'处理是依赖于实现的,那么'return(Math.random()> 0.5)怎么样? -1:1;'在'shuffle()'体内? – sparklewhiskers

+0

谢谢,我已经更新了shuffle功能。 –

0

被盗从user113716,但优化了一点。

var arr = [ 
    "ppc", 
    "games", 
    "advertise", 
    "meta", 
    "home", 
    "gaming", 
    "welcome"]; 

Array.prototype.shuffle = Array.prototype.shuffle || function() { 
    var copy = this.slice(), arr = []; 
    while (copy.length) arr.push(copy.splice((Math.random() * copy.length) << 0)); 
    return arr; 
}; 

alert(arr.shuffle());