Javascript 生成唯一的idsjs

Javascript 生成唯一的idsjs,javascript,arrays,jasmine,Javascript,Arrays,Jasmine,在Jasmine中运行一些测试,试图让代码正常工作,发现ID不是唯一的。这是有道理的,因为它们是随机生成的 var Robot = function(){ this.name = makeid(); function makeid() { var text = ""; var possible ="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for( var i=0; i < 2; i++ ){

在Jasmine中运行一些测试,试图让代码正常工作,发现ID不是唯一的。这是有道理的,因为它们是随机生成的

var Robot = function(){
    this.name = makeid();
    function makeid()
    {
        var text = "";
        var possible ="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        for( var i=0; i < 2; i++ ){
            text += possible.charAt(Math.floor(Math.random() * possible.length));
        }
        var possibleNums ="0123456789";
        for( var j=0; j < 3; j++ ){
            text += possibleNums.charAt(Math.floor(Math.random() * possibleNums.length));
        }
        return text;
    }
};
var Robot=function(){
this.name=makeid();
函数makeid()
{
var text=“”;
var-mable=“abcdefghijklmnopqrstuvxyz”;
对于(变量i=0;i<2;i++){
text+=可能的.charAt(Math.floor(Math.random()*可能的.length));
}
var possibleNums=“0123456789”;
对于(var j=0;j<3;j++){
text+=possibleNums.charAt(Math.floor(Math.random()*possibleNums.length));
}
返回文本;
}
};
我需要它来完成这个测试

it('there can be lots of robots with different names each', function() {
    var i,
        numRobots = 10000,
        usedNames = {};

    for (i = 0; i < numRobots; i++) {
      var newRobot = new Robot();
      usedNames[newRobot.name] = true;
    }
    expect(Object.keys(usedNames).length).toEqual(numRobots);
  });
it('可以有很多机器人,每个机器人的名字不同',函数(){
var i,
numRobots=10000,
usedNames={};
对于(i=0;i
我的理论是,我可能能够创建一个数组,将每个名称推送到其中,然后比较唯一性。这看起来可能令人沮丧。我想知道是否有另一种方法,也许可以保证生成时的唯一性,或者使用一些不涉及数组的简单比较工具


编辑:日期戳方法将是确保唯一id的一个很好的方法,但不幸的是,我不得不使用我用来通过另一个测试的id生成方法。基本上,我需要id为5个字符,2个大写字母后接3个数字。

您可以使用
Date.now()
,以毫秒为单位返回日期和时间:
1463004819469

Date.now()。假设您的程序没有多个线程,那么事情必须按顺序进行,这样就不会有两个相同的ID

例如:

var Robot = function(){
    this.name = Date.now(); //1463004819469
}
希望这能解决你的问题


编辑:如果您连续两次调用
new Robot()
,可能会得到相同的ID。您可以将
Date.now()连接到自定义唯一ID或随机数,如下所示:

  • this.name=String(Date.now())+Math.floor(Math.random()*10000)
  • this.name=String(Date.now())+makeid()
  • this.name=String(Date.now())+String(counter)//每次创建Robot时增加该值
这些只是示例,您可以创建任何您想要的组合

老实说,你为什么不用柜台呢?像这样:

var counter = 0;
var Robot = function(){
    counter++;
    this.name = counter;
}

除非ID也存在于程序之外,所以在这种情况下,这将不起作用。

这是我在JS代码中使用的函数:

function uniqueid() {
    // always start with a letter (for DOM friendlyness)
    var idstr = String.fromCharCode(Math.floor((Math.random() * 25) + 65));
    do {
        // between numbers and characters (48 is 0 and 90 is Z (42-48 = 90)
        var ascicode = Math.floor((Math.random() * 42) + 48);
        if (ascicode < 58 || ascicode > 64) {
            // exclude all chars between : (58) and @ (64)
            idstr += String.fromCharCode(ascicode);
        }
    } while (idstr.length < 32);

    return (idstr);
}
函数uniqueid(){
//始终以字母开头(表示对DOM的友好)
var idstr=String.fromCharCode(Math.floor((Math.random()*25)+65));
做{
//在数字和字符之间(48为0,90为Z(42-48=90)
var ascicode=Math.floor((Math.random()*42)+48);
如果(ascicode<58 | | ascicode>64){
//排除介于(58)和@(64)之间的所有字符
idstr+=String.fromCharCode(ascicode);
}
}而(idstr.length<32);
返回(idstr);
}

如果您只需要一个您自己页面独有的id,只需一个计数器即可:

var unique = (function() {
    var cntr = 0;
    return function(prefix) {
        prefix = prefix || "";
        return prefix + cntr++;
    }
})();

console.log(unique("myid"));   // "myid0"
console.log(unique("myid"));   // "myid1"
在代码中使用该选项:

var unique = (function() {
    var cntr = 0;
    return function(prefix) {
        prefix = prefix || "";
        return prefix + cntr++;
    }
})();

var Robot = function(){
    this.name = unique("robot");
};
单调递增的计数器是确保在此范围内生成唯一名称所需的全部


如果要生成在所有客户端中很可能是唯一的字符串,可以使用以下答案中的类似内容:


如果您想在世界上所有页面/用户中获得完全的保证,那么您必须使用中央服务器来协调和分配唯一值,或者使用一些已知的唯一客户端种子(对于PC上的GUID生成器来说,使用以太网mac地址作为种子是很常见的,因为这些不会在其他计算机上重复).

稍微修改一下你的代码,你就可以得到保证唯一的ID,但我不建议像100000+这样的机器人大军使用这种方法,因为它的速度非常慢

var Robot = function(){
    this.name = this.makeId();
};

Robot.prototype.makeId = function makeId(){
  var     text = "",
      possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
  possibleNums = "0123456789";
  for( var i=0; i < 2; i++ ){
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }

  for( var j=0; j < 3; j++ ){
    text += possibleNums.charAt(Math.floor(Math.random() * 10));
  }
return !~Robot.prototype.ids.indexOf(text) ? (Robot.prototype.ids.push(text),text) : makeId();
};

Robot.prototype.ids = [];

function robotFactory(n){
  a = [];
  for(var i = 0; i < n; i++) a.push(new Robot());
  return a;
}

var myRobotArmy = robotFactory (10000);

我知道这个问题更为具体,但也许像我这样的人只是在寻找一条获取身份证的捷径。我从中找到了一个解决方案 gist.github.com/gordonbrander/2230317作者:gordonbrander/ID.js

  var ID = function () {
  // Math.random should be unique because of its seeding algorithm.
  // Convert it to base 36 (numbers + letters), and grab the first 9 characters
  // after the decimal.
  return '_' + Math.random().toString(36).substr(2, 9);
};

在生成的代码中添加一个唯一的数字,如
[generateId]+“00001”
等等…
[generateId]+“00002”
[generateId]+“00003”
…但这更像是一个快捷方式,一个不好的方式:)您可以使用任何GUID库来创建唯一的名称,或者只使用
this.name=Robot.totalCount++
此项的可能重复并不保证任何事情<代码>新机器人();新机器人()
很可能会创建两个同名机器人。@BryanChen,你满意吗?如果是,请删除下一票:)(如果您这样做了)。@Mirabilis或只使用带有时间戳的计数器,例如:
Date.now()+““+(counter++)
Date.now()的多次调用肯定可以生成相同的值。这里的证据:。请从你的答案的第一部分中删除这一说法。我不同意你的看法——“我想知道是否有其他方法,也许可以保证这一代人的独特性……”甚至你自己的答案也详细说明了一种使人独特的方法。这就是问题的核心所在,我从来没有发表过这样的评论。当我折断手指时,你会忘记整件事。事实上,这正是我所需要的,我必须更改,文本):makeId();to,text):this.makeId();但除此之外,它工作得非常出色。是否有一些文档可以链接到该返回语句或对其进行简单解释?我真的不太确定那里发生了什么。@Zack Lucky:嗨,返回语句实际上只不过是