【问题标题】:making sure my array of random values doesn't contain duplicate values确保我的随机值数组不包含重复值
【发布时间】:2012-06-14 14:24:13
【问题描述】:

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

【问题讨论】:

    标签: javascript jquery random


    【解决方案1】:

    创建一个临时数组,它是 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);
    

    然后您可以在每次将元素添加到arr2 时从temp_arr 中删除它。由于我们在复制字符串时使用了对象键,所以我们可以在推入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);
    

    【讨论】:

    • 感谢 Paul,但我需要将 arr1 中的值保留在那里,不过会更新该 rand
    • arr1 中有重复项,因此删除选取的元素并不能确保arr2 中没有重复项。
    • @Guffa 啊,我明白了,现在更新我的答案。
    • @styler 我已经更新了我的答案,所以它会保持arr1 不变并且在arr2 中只有唯一值
    • 嗨,保罗,这看起来不错!虽然有 1 个问题,我认为 for 循环必须有一个起始值、结束值和增量?
    【解决方案2】:

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

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

    var set = {};
    set['0'] = true;
    set['1'] = true;
    
    if(set.hasOwnProperty('0')) {
        alert("duplicate 0!");
    }
    

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        试试这个

        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] );
            }
        

        【讨论】:

          【解决方案5】:

          通过使用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 );
          

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多