-3

Say I pick 10 random numbers between 1 and 12 and put them into an array. How can I loop through it so to eliminate duplicates?

I have spent a lot of time on this and cant get it to work.

5 Answers5

1

If you want 15 random integers between 1 and 20 without duplicates, that's most of the integers in your range. I would just generate the numbers 1-20 and remove a random one 15 times:

function randomIntegersInRange(min:int, max:int, count:uint):Array {
    if (min >= max || count > max - min) throw new ArgumentError("Invalid arguments!");
    var integers:Array = [];
    for (var i:int = min; i <= max; i++) {
        integers.push(i);
    }

    var randomIntegers:Array = [];
    for (i = 0; i < count; i++) {
        randomIntegers.push(integers.splice(Math.random() * integers.length, 1));
    }
    return randomIntegers;
}

randomIntegersInRange(1, 20, 15); // 16,4,3,13,8,17,1,19,20,15,6,18,14,10,12
randomIntegersInRange(1, 50, 20); // 27,3,19,9,42,23,13,29,11,24,41,31,26,2,7,30,49,33,6,10

Note: I wouldn't recommend this if you want massive ranges, like 15 integers between 1 and 1,000,000.

Aaron Beall
  • 49,769
  • 26
  • 85
  • 103
  • But if i would want random numbers? Lets for example say from 1-50 and then pick 20 without getting any duplicates? –  Mar 06 '16 at 20:37
  • This gives you random numbers. If you want to parameterize the ranges, just change `20` and `15` above into variables. – Aaron Beall Mar 06 '16 at 20:39
  • @CollapsedSounds Edited my answer into a function with params for range and count. – Aaron Beall Mar 06 '16 at 20:43
  • Thank you for this answer. However i got one more question. When i try to call out this function lets say from a button it says "Implicit coercion of a value type Array to unrelated type Function." How do i handle this? –  Mar 06 '16 at 21:03
  • It sounds like you tried `addEventListener("evt", randomIntegers(1, 20, 15))` but you need to *pass* a function as a handler, not *call* a function. You can call this function from a handler like `addEventListener("evt", handler); function handler(e:Event):void { randomIntegers(1, 20, 15) }` – Aaron Beall Mar 06 '16 at 22:54
0

Do a recursive approach,

function pushIt(arr){
 var idx:int;
 if(arr.length == 10){ return arr; }
 else { 
   idx = Math.floor(Math.random() * 12) + 1;
   if(arr.indexOf(idx) == -1){ arr.push(idx); } 
   return pushIt(arr);
 }
}

console.log(pushIt([]));
Rajaprabhu Aravindasamy
  • 66,513
  • 17
  • 101
  • 130
0

[5, 1, 8, 4, 10, 9, 11, 2, 6, 7]

function generateUniqueArray(length, rangeMax){
  var arr = [];
  while(arr.length < length) {
    var rand = Math.ceil(Math.random()*rangeMax);
    var isInArr = false;
    for(var i = 0; i<arr.length;i++){
      if(arr[i]===rand){
        isInArr = true;
        break;
      }
    }
    if (!isInArr){
      arr[arr.length]=rand;
    }
  }
  return arr;
}

console.log(generateUniqueArray(10,12));
user2950720
  • 931
  • 2
  • 10
  • 26
0

You could put them into a hash (js object) and then return the keys in the hash:

function getUniques(arr){
   var seen = {};
   arr.forEach(function(item){
     seen[item] = true;
   });
   return Object.keys(seen);
}
Tate Thurston
  • 4,236
  • 1
  • 26
  • 22
0

There are two aproaches to this problem:

Create a random number, check wether it has already been picked, if not, add this value to the output.

var numbers = [];
while(numbers.length < 10){
    var nr = Math.floor(Math.random() * 12)+1
    if(numbers.indexOf(nr) === -1) numbers.push(nr);
    else console.log("threw away ", nr);
}

This works pretty good, if you want to select a small amount of numbers out of a big range, since here it is likely to hit few collisions (picking the same random number over and over again, and having to throw it away).

In your case 10 values out of a range of 12, It's pretty likely that you will have a lot of hits during the end where the code has to create random numbers over and over and over again to find another number that's not already in your set.

So we get to the second aproach: create a set containing all possible values, shuffle it, and then take a slice out of that.

//a helper to shuffle the array
function shuffle(arr){
    for(var i=arr.length; --i > 0; ){
        var j = Math.floor(Math.random() * i);
        var tmp = arr[j];
        arr[j] = arr[i];
        arr[i] = tmp;
    }
    return arr;
}

//a helper to create a sequence ov values
function range(from, to, step){
    step = Math.abs(+step) || 1;
    to = +to || 0;
    var i = +from || 0, out = [];
    if(i > to) while(i>to) out.push(i), i -= step;
    else while(i<to) out.push(i), i += step;
    return out;
}

var numbers = shuffle(range(1,13)).slice(0, 10);

This would create a way to big overhead, if you would need only a small set out of a huge range of values

Thomas
  • 3,513
  • 1
  • 13
  • 10