最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - making sure my array of random values doesn't contain duplicate values - Stack Overflow

programmeradmin3浏览0评论

I was wondering if anyone can advise how I can make sure the random array I'm generating from another array doesn't contain duplicate values, want to make sure that arr2 contains unique values?

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

Maybe an if statement that pares arr1[rand] with arr2[i] ?

I was wondering if anyone can advise how I can make sure the random array I'm generating from another array doesn't contain duplicate values, want to make sure that arr2 contains unique values?

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

Maybe an if statement that pares arr1[rand] with arr2[i] ?

Share Improve this question edited Jun 14, 2012 at 16:08 Paul 142k28 gold badges284 silver badges271 bronze badges asked Jun 11, 2012 at 16:41 stylerstyler 16.5k25 gold badges85 silver badges139 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 6

Create a temporary array that is a copy of arr1 containing only unique values:

// 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);

Then you can remove the element from temp_arr each time you add it to arr2. Since we used object keys when copying we have strings, so we can use + to convert them back to numbers when pushing into arr2:

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

You should also change how you pick random numbers to:

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

Whole code:

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

The naive O(n^2) solution is to simply check each element and see if any other position in the array has the same value.

A linear time solution can be achieved using a hashset data structure. You can hack one in JavaScript using objects:

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

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

If the numbers are integers and relatively small, then you can keep track of them in an array of boolean values.

See http://bost.ocks/mike/shuffle/ for good info on the Fischer/Yates shuffle. For your problem, you could take the first five elements of the shuffled deck.

try this

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

By using jQuery.inArray function :)

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 );
发布评论

评论列表(0)

  1. 暂无评论