2011-08-20 89 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());