2012-05-21 92 views
3

从1000个元素的数组中获得50个随机唯一元素的最简单方法是什么?来自1000个元素阵列的50个随机独特元素?

text = new Array(); 
for(i=0;i<1000;i++){ text[i]=i; } //array populated 
// now I need to get 50 random unique elements from this array. 
+0

50个独特元素? – JoshNaro

+0

是的,独特的元素。 – xRobot

+2

你是什么意思的独特元素?你是指索引中的唯一索引或唯一值? – epascarello

回答

-2

Math.random()* 1000;

生成50个随机数并将它们用作数组中的位置。

+1

以这种方式我没有得到独特的元素:) – xRobot

+0

我在这里做一些假设。我假设你正在检查你的随机值,就像我假设你知道如何在没有我的情况下存储这50个数字:) – Limey

0

设置一个变量等于Math.random(),每次循环运行时调用该变量并将该变量作为索引。按照数组大小调整随机调用,在这种情况下为1000.这会给你50个随机元素。

1

好算法this topic解释(在C,但你可以很容易地在JS做相同)

3

明显的(对我)的办法就是重新洗牌的阵列,然后采取前五元素。 This question有一个很好的方式来洗牌一个数组,然后你可以在第一个五十个元素中使用slice。这保证了元素将是唯一的。

因此,使用该功能有:

fisherYates(text); 
text = text.slice(0, 50); 
+1

好主意!但是,只有1000个元素是唯一的,它才会起作用。 – VisioN

+0

@VisioN在这种情况下,确保'text'中的元素是唯一的。有很多功能可以用来做这个,比如[this one](http://www.jslab.dk/library/Array.unique)。 – lonesomeday

+0

VisioN是正确的,洗牌1000个len阵列也很昂贵 – ajax333221

0

如果你的意思是唯一值:

Demo

var old_arr = [0,1,2,3,4,5,6,7,8,9], new_array = []; 

for (var i = 0; i < 5; i++) { 
    var rand_elem = old_arr[Math.floor(Math.random() * old_arr.length)]; 

    if (arrIndex(old_arr[rand_elem], new_array) == -1) { 
     new_array.push(rand_elem); 
    } else { 
     i--; 
    } 
} 

function arrIndex(to_find, arr) {//own function for IE support 
    if (Array.prototype.indexOf) { 
     return arr.indexOf(to_find); 
    } 
    for (var i = 0, len = arr.length; i < len; i++) { 
     if (i in arr && arr[i] === to_find) { 
      return i; 
     } 
    } 
    return -1; 
} 

如果你的意思是独特的指数法:

  • 随机生成索引和索引存储在一个阵列中,并使检查以防止重复
  • 开始删除元素o F中的阵,你让他们后,(你可能会如果缓存长度有问题,所以不要)
0
var arr = []; 
while(arr.length < 51){ 
    var ind = Math.floor(Math.random()*1000); 
    if(!(ind in arr)) 
     arr.push(ind) 
} 

您将有50个随机识别号数组ARR,你可以使用作为指数

编辑:

正如@ ajax333221提到,以前的代码没有得到从数组的独特元素,在情况下,它包含重复。因此,这是修复:

var result_arr = []; 
while(result_arr.length < 51){ 
    var ind = Math.floor(Math.random()*1000); 
    if(text[ind] && !(text[ind] in result_arr)) 
     result_arr.push(text[ind]); 
} 

是“文”填充1000个值

+0

-1 a)不会正确生成唯一编号b)即使您修复它,如果1k数组包含重复项,那么唯一编号也是无用的 – ajax333221

+0

是的,您错了,我误解了这个问题,索引号码。你为什么说它不会正确生成唯一的数字? – davids

+1

@d因为'if(!(ind in arr))'不是正确的检查,它会检查索引是否包含在数组中(而不是数值)。所以如果你在第一个循环中添加23,23可能会复制下一个循环。你可能想用indexOf代替 – ajax333221

0

这里假设你的意思是随机指标,而不是指标具有唯一值的数组。

一种方法是在阵列复制剪掉你使用的:

function getRandomIndexes(arr, cnt){ 
    var randomArr = [], 
     arrCopy = arr.slice(), 
     i, 
     randomNum ; 
    for (i=0;i<arrCopy.length;i++) { 
     randomNum = Math.floor(arrCopy.length * Math.random()); 
     randomArr = randomArr.concat( arrCopy.splice(randomNum ,1)); 
    }  
    return randomArr; 
} 

var myNums = [], i, randSet; 
for (i=0;i<10;i++){ 
    myNums.push(i); 
} 
randSet = getRandomIndexes(myNums, 5); 

另一种方法是跟踪使用指标和继续找,直到你找到一个你没有使用。我发现while循环是可怕的,如果随机索引需要接近数组长度,我个人不会使用这个解决方案。

function getRandomIndexes(arr, cnt){ 
    var randomArr = [], 
     usedNums = {}, 
     x; 
    while (randomArr.length<cnt) { 
     while (usedNums[x]===true || x===undefined) { 
      x = Math.floor(Math.random() * arr.length); 
     } 
     usedNums[x] = true; 
     randomArr.push(arr[x]); 
    } 
    return randomArr; 
} 

var myNums = [], i, randSet; 
for (i=0;i<10;i++){ 
    myNums.push(i); 
} 
randSet = getRandomIndexes(myNums, 5); 
+0

有趣,第一次看到'arr.slice()'(我总是看到'arr.slice(0)'),但我想它也可以工作 – ajax333221