我有一個數組(說'origA'),其中包含20個值和另一個數組(說「itemA」只有1值,我需要推任何10隨機值「ORIGA」到「意達」的,但我不能把它已經被推到「意達」相同的值。從一個數組到另一個數組傳遞隨機值沒有重複
我們怎樣才能做到這一點?
我有一個數組(說'origA'),其中包含20個值和另一個數組(說「itemA」只有1值,我需要推任何10隨機值「ORIGA」到「意達」的,但我不能把它已經被推到「意達」相同的值。從一個數組到另一個數組傳遞隨機值沒有重複
我們怎樣才能做到這一點?
// 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);
}
您可以創建一個副本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
沒有電話,indexOf
,splice
或push
環內):
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
不錯,雖然我用一個長度爲10或甚至在100以下的數組工作,但並不真的需要一個沒有indexOf()的解決方案,儘管我承認這對於尋找類似解決方案array :) – Marty 2012-04-16 07:46:42
我使用原始數組的副本主要是爲了避免改變它(使用'splice()'),而不是避免使用'indexOf()'。只有在第二個優化版本中,我才避免調用昂貴的方法:'length','indexOf','splice'和'push'。 – sch 2012-04-16 07:51:46
我必須同意'indexOf()'部分 - 它將從索引0開始迭代,直到找到該項目,這對於更大的數組來說可能相當昂貴。 – weltraumpirat 2012-04-16 08:39:59
這是一個真正的短。從原來的數組中刪除隨機項目,直到你達到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循環。
他確實說過「隨機」,你知道...... – weltraumpirat 2012-04-16 07:03:09
如果我不清楚,但我需要任何10個沒有重複的隨機值,不是全部。 – Sravan0313 2012-04-16 07:07:01
@Marty華萊士所有的價值是不同的,在「origA」這個問題不應該發生。無論如何,當我說沒有重複時,我的意思是如果一個隨機值從「origA」被推入「itemA」中,則不應再次推送相同的值。你明白我的意思嗎? – Sravan0313 2012-04-16 07:13:05