0

My requirement is to generate 5 digit unique code which is not in the list already.

For example if I have [12345, 54321, 13245, 11234], I would like to generate 34522 etc.. I am using below code for it

function id(){
    var text = "", can = "12345";
    for( var i = 5; i--; text += can.charAt(Math.floor(Math.random() * can.length)));
    return text;
}

var list = [12345, 54321, 13245, 11234];
var generated;
while(!generated){
   var t = makeid();
      if(list.indexOf(t) == -1){
          generated = t;
      }
}

This works fine, but when list grows, this would take more time(?). Are there any other ways to write this mechanism.

redV
  • 684
  • 1
  • 9
  • 26
  • If it's just numbers you can use a hash approach. `var seen={}`, then `if(!(x in seen)){seen[x]=1}`. That will be faster. – elclanrs Sep 04 '14 at 23:29
  • @elclanrs Yes that's true. But assuming list as an array there are many operations that I cant change. Sorry – redV Sep 04 '14 at 23:31
  • 3
    You're missing the point, I mean use an object as cache, instead of calling `indexOf` on the array. Keep the cache in a closure. – elclanrs Sep 04 '14 at 23:31
  • @elclanrs Like `var obj = {}, for(var i = list.length; i--; obj[list[i]] = true)` and then `if(t in obj)`? – redV Sep 04 '14 at 23:34

1 Answers1

1

As @elclanrs said, better use a hash approach

var obj = {};
for(var i=0; i<list.length; ++i) { obj[list[i]] = true; }

and then check

obj.hasOwnProperty(t);

Better use hasOwnProperty and not in to avoid searching in the prototype chain.


However, you can simplify it using ES6 Set:

var set = Set(list);

and then check

set.has(t)

Note not all browsers support it yet.


Be aware that id returns a string, but list is an array of numbers!

To fix that, convert the id to a number (e.g. with unary +), or use something like

function id() {
    var num = 0, len = 5;
    for(var i=0; i<len; ++i) {
        num *= 10;
        num += Math.floor(Math.random() * len) + 1;
    }
    return num;
}
Community
  • 1
  • 1
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • Thanks for the answer. I used the same approach and made hash like below rather using for loop `JSON.parse('{"' + (list.split(',').join('":0,"')) + '":0}');` – redV Sep 05 '14 at 01:14