2

我想知道是否有人可以建议我如何确保我从另一个数组生成的随机数组不包含重复值,想确保 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 语句?

4

5 回答 5

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);
于 2012-06-11T16:44:47.277 回答
2

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

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

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

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

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

于 2012-06-11T16:43:52.333 回答
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 );
于 2012-06-11T19:25:56.297 回答
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] );
    }
于 2012-06-11T16:44:05.383 回答
1

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

于 2012-06-11T16:48:22.457 回答