2016-02-19 53 views
0

我有以下函數可以從數組中抽出一個隨機索引而不重複索引,並保持拉出它們直到所有的索引都被使用,然後重置自身並開始重新使用他們。它也嘗試,以確保最後一個拉出的是不一樣的復位拉出來的下一個,所以你永遠不會有相同的索引連續出來。退出函數並再次調用本身而不返回undefined

var listIndexes = []; 
var lastIndex; 

function getRandomIndex(indexes) 
{ 
    if (!listIndexes.length) { 
     for (var i = 0; i < indexes; i++) { 
      listIndexes.push(i); 
     } 
    } 

    var randomIndex = Math.floor(Math.random() * listIndexes.length); 
    var uniqueIndex = listIndexes[randomIndex]; 

    listIndexes.splice(randomIndex, 1); 

    if(lastIndex && uniqueIndex == lastIndex) 
    { 
     listIndexes = []; 
     getRandomIndex(indexes); 
     return; 
    } 

    lastIndex = uniqueIndex; 

    return uniqueIndex; 
} 

var index = getRandomIndex(5); 

console.log(index); 

但是當它擊中代碼:if(lastIndex && uniqueIndex == lastIndex)這導致它的索引返回undefined。所以我試圖退出函數並重新調用函數以重試的方式不能按計劃運行。

如何退出當前函數調用並重新調用該函數以獲取與lastIndex不相同的新隨機索引。請注意,lastIndex保持不變,直到新索引不一樣,無論該函數被調用多少次。

回答

2

試試這個:

if(lastIndex && uniqueIndex == lastIndex) 
    { 
     listIndexes = []; 
     return getRandomIndex(indexes); 
    } 
1

只是改變你的空返再次運行功能:

return getRandomIndex(indexes); 
1

重新拋出模具的,當你沒有得到你想要的結果的方法是不最優,當隨機數不是很隨機的時候(往往會重複相同的數字),那麼你就不必要地進行循環。

嘗試這種情況:

function RandEleGenerator(list) { 
    var lastChosen; 
    var currentList = list.slice(); 

    function randomIndex() { 
     return Math.floor(Math.random() * currentList.length); 
    } 
    return function() { 
     // Choose element 
     var index = randomIndex(); 
     var obj = currentList[index]; 

     // Remove it from current list 
     currentList.splice(index, 1); 
     if(currentList.length == 0) { 
      // If empty, restore list 
      currentList = list.slice(); 

      // But not without removing last chosen element 
      index = currentList.indexOf(obj); 
      currentList.splice(index, 1); 
     } 
     return obj; 
    }; 
} 

用法:

var reg = new RandEleGenerator([1,2,3]); 
reg(); // 3 
reg(); // 2 
reg(); // 1 
reg(); // 2 
reg(); // 3 
reg(); // 2 
reg(); // 1 

所選擇的元素從所述列表中移除,因此它不能被rechosen。爲了保證列表結束時不重複某個值,將重新創建該列表,並立即從列表中刪除所選的最後一個元素。然後該過程繼續隨機選擇要從列表中移除的元素。

編輯: 爲了說,生成一個數組傳遞給RandEleGenerator,下面的代碼就足夠了:

var arrToPass = []; 
for (var i = 0; i < 3; i++) { 
    arrToPass.push(i); 
} 
var reg = new RandEleGenerator(arrToPass); 
+0

可以只用一個號碼這項工作?因爲我不想傳遞它實際的數組只是數字,所以在你的例子中,我只是想通過它'RandEleGenerator(3);' – Cameron

+0

@Cameron你已經有了代碼來構造數組[1 (var i = 0; i Neil

+0

你能告訴我一個我怎麼做的例子,因爲我沒有遵循你的意思。乾杯朋友。 – Cameron