2012-04-16 70 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循环。

相关问题