2012-04-16 103 views

回答

2
// Define how many random numbers are required. 
const REQUIRED:int = 10; 

// Loop until either the original array runs out of numbers, 
// or the destination array reaches the required length. 
while(origA.length > 0 && itemA.length < REQUIRED) 
{ 
    // Decide on a random index and pull the value from there. 
    var i:int = Math.random() * origA.length; 
    var r:Number = origA[i]; 

    // Add the value to the destination array if it does not exist yet. 
    if(itemA.indexOf(r) == -1) 
    { 
     itemA.push(r); 
    } 

    // Remove the value we looked at this iteration. 
    origA.splice(i, 1); 
} 
+0

他確實說過「隨機」,你知道...... – weltraumpirat 2012-04-16 07:03:09

+0

如果我不清楚,但我需要任何10個沒有重複的隨機值,不是全部。 – Sravan0313 2012-04-16 07:07:01

+0

@Marty華萊士所有的價值是不同的,在「origA」這個問題不應該發生。無論如何,當我說沒有重複時,我的意思是如果一個隨機值從「origA」被推入「itemA」中,則不應再次推送相同的值。你明白我的意思嗎? – Sravan0313 2012-04-16 07:13:05

3

您可以創建一個副本origA並從中刪除您添加到itemA的項目:

非優化的版本:

var origA:Array = [1, 2, 3, 4, 5, 6, 7]; 
var itemA:Array = [0]; 

var copyA:Array = origA.concat(); 
var N:int = 10; 
var n:int = Math.min(N, copyA.length); 

for (var i:int = 0; i < n; i++) { 
    // Get random value 
    var index:int = Math.floor(Math.random() * copyA.length); 
    var value:int = copyA[index]; 
    // Remove the selected value from copyA 
    copyA.splice(index, 1); 
    // Add the selected value to itemA 
    itemA.push(value); 
} 

trace(itemA); 
//0,1,7,2,6,4,3,5 

優化的版本(以length沒有電話,indexOfsplicepush環內):

var origA:Array = [1, 2, 3, 4, 5, 6, 7]; 
var itemA:Array = [0]; 

var copyA:Array = origA.concat(); 
var copyALength:int = copyA.length; 
var itemALength:int = itemA.length; 
var N:int = 10; 
var n:int = Math.min(N, copyALength); 
for (var i:int = 0; i < n; i++) { 
    // Get random value 
    var index:int = Math.floor(Math.random() * copyALength); 
    var value:int = copyA[index]; 
    // Remove the selected value from copyA 
    copyA[index] = copyA[--copyALength]; 
    // Add the selected value to itemA 
    itemA[itemALength++] = value; 
} 

trace(itemA); 
//0,2,5,7,4,1,3,6 

EDIT1:如果你原來的數組只有幾個項目,在其他答案中使用我的第一個版本或任何其他解決方案。但是,如果它可能有數千個項目或更多,那麼我建議您使用我的優化版本。


編輯:2這裏是從含有1,000,000項的數組複製1,000隨機選擇的項目所花費的時間:

  • 所有其他版本:2000ms
  • 優化版本:12ms
  • 無需克隆原始陣列的優化版本:1ms
+0

不錯,雖然我用一個長度爲10或甚至在100以下的數組工作,但並不真的需要一個沒有indexOf()的解決方案,儘管我承認這對於尋找類似解決方案array :) – Marty 2012-04-16 07:46:42

+0

我使用原始數組的副本主要是爲了避免改變它(使用'splice()'),而不是避免使用'indexOf()'。只有在第二個優化版本中,我才避免調用昂貴的方法:'length','indexOf','splice'和'push'。 – sch 2012-04-16 07:51:46

+0

我必須同意'indexOf()'部分 - 它將從索引0開始迭代,直到找到該項目,這對於更大的數組來說可能相當昂貴。 – weltraumpirat 2012-04-16 08:39:59

2

這是一個真正的短。從原來的數組中刪除隨機項目,直到你達到MAX,然後CONCAT到目標磁盤陣列:

const MAX:int = 10; 
var orig:Array = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; 
var target:Array = []; 
var tmp:Array = []; 
var i : int = -1; 
var len : int = orig.length; 
while (++i < MAX && len > 0) { 
    var index:int = int(Math.random()*len); 
    tmp[i] = orig[index]; 
    orig[index] = orig[--len]; 
} 
target = target.concat(tmp); 

編輯刪除項目的

採納@ SCH的方式。這是他應該接受的答案。我只保留了這個while循環。

相關問題