确保我的随机值数组不包含重复值

时间:2012-06-11 16:41:46

标签: javascript jquery random

我想知道是否有人可以建议我如何确保我从另一个数组生成的随机数组不包含重复值,是否要确保arr2包含唯一值?

JS

var limit = 5,
    i = 0,
    arr1 = [12, 14, 67, 45, 8, 45, 56, 8, 33, 89],
    arr2 = [];

    for ( i; i < limit; i++ ){
        var rand = Math.floor((Math.random()*9)+1);
        arr2.push( arr1[rand] );
    }

    console.log(arr2);

可能是一个将arr1 [rand]与arr2 [i]进行比较的if语句?

5 个答案:

答案 0 :(得分:6)

创建一个临时数组,该数组是仅包含唯一值的arr1的副本:

// Copy unique values in arr1 into temp_arr
var temp_obj = {}, temp_arr = [], i;
for(i = arr1.length; i--;)
    temp_obj[arr1[i]] = 1;
for(i in temp_obj) 
    temp_arr.push(i);

然后,每次将元素添加到temp_arr时,都可以从arr2中删除该元素。由于我们在复制时使用了对象键,因此我们有字符串,因此我们可以在推入+时使用arr2将它们转换回数字:

arr2.push(+temp_arr.splice(rand, 1)[0]);

您还应该更改随机数字的选择方式:

var rand = Math.floor(Math.random()*temp_arr.length);

整个代码:

var limit = 5,
  arr1 = [12, 14, 67, 45, 8, 45, 56, 8, 33, 89],
  arr2 = [],
  rand, 
  temp_obj = {},
  temp_arr = []
  i;

// Copy unique values from arr1 into temp_arr
for(i = arr1.length; i--;)
    temp_obj[arr1[i]] = 1;
for(i in temp_obj)
    temp_arr.push(i);;

// Move elements one at a time from temp_arr to arr2 until limit is reached
for (var i = limit; i--;){
    rand = Math.floor(Math.random()*temp_arr.length);
    arr2.push(+temp_arr.splice(rand, 1)[0]);
}

console.log(arr2);

答案 1 :(得分:2)

朴素的O(n^2)解决方案是简单地检查每个元素,看看数组中的任何其他位置是否具有相同的值。

使用哈希集数据结构可以实现线性时间解决方案。您可以使用对象在JavaScript中破解一个:

var set = {};
set['0'] = true;
set['1'] = true;

if(set.hasOwnProperty('0')) {
    alert("duplicate 0!");
}

如果数字是整数且相对较小,那么您可以在布尔值数组中跟踪它们。

答案 2 :(得分:1)

试试这个

for ( i; i < limit; i++ ){
        var rand = Math.floor((Math.random()*9)+1);
        for(j=0; j <  arr1.length; j++)
           if(rand == arr1[j]
           { 
                blnfound = true;
                break;
           }
        if(!blnfound)
        arr2.push( arr1[rand] );
    }

答案 3 :(得分:1)

有关Fisher / Yates shuffle的详细信息,请参阅http://bost.ocks.org/mike/shuffle/。对于你的问题,你可以采用洗牌组的前五个元素。

答案 4 :(得分:1)

使用jQuery.inArray功能:)

var limit = 5,
arr1 = [12, 14, 67, 45, 8, 45, 56, 8, 33, 89],
l = arr1.length,
arr2 = [];

while( limit ){
      var tmp = arr1[  Math.random() * l | 0 ];  
      // for unsigned numbers '|0' construction works like Math.floor  
      if( !~$.inArray( tmp, arr2 ) ) { 
       // if not found $.inArray returns -1 ( == ~0 ), then !~-1 == true   
          limit--;
          arr2[ arr2.length ] = tmp;
      } 
} 
console.log( arr2 );