在 Jasmine 中运行一些测试试图让这段代码工作,发现 ids 不是唯一的。这是有道理的,因为它们是像这样随机生成的。
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;
}
};
我需要它来完成这个测试。
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);
});
我推测我可以制作一个数组,将每个名称推送到它,然后比较唯一性。这看起来可能令人沮丧。我想知道是否有另一种方法,也许是为了保证生成时的唯一性或一些不涉及数组的简单比较工具。
编辑:日期戳方法将是确保唯一 ID 的好方法,但不幸的是,我必须使用我用来通过另一项测试的 ID 生成方法。本质上,我需要 id 为 5 个字符,后跟 2 个大写字母和 3 个数字。
原文由 Zack Lucky 发布,翻译遵循 CC BY-SA 4.0 许可协议
稍微修改你的代码,你可以获得有保证的唯一 ID,但我不建议像 100000+ 这样的机器人大军这样做,因为它变得非常慢。
编辑@2017 年 8 月 18 日
检查上面的代码我认为我可以做得更好。特别是在
indexOf
部分,这是一个巨大的性能瓶颈。现在它运行得更快了。此外,我可以通过将不必要的数据和功能从实例化对象的访问中隐藏起来,从而更好地塑造构造函数,方法是将它们设为私有。另一件事是所需的命名方案只允许 676,000 个名称(26 x 26 x 10 x 10 x 10),因此要求更多的机器人将导致堆栈溢出,因为我们将拥有所有可能的名称,但仍在尝试生成一个唯一的名称。这当然可以通过从一开始就限制军队规模来避免。但是再想一想,要一支由 676,000 名机器人组成的军队。随机名称生成器的失败率将随着使用过的名称在哈希表中的堆积而增加。根据姓氏,我们将不得不尝试数十万个随机名字,直到我们得到最后一个唯一的名字。在这种特殊情况下,您有两种解决方案;