脚本返回不一致长度的字符串

0 javascript recursion

此脚本的目的是打印由破折号分隔的随机生成的字母数字值的8个"块",以创建39个字符的唯一ID.

E7L9-XNP4-UB4K-10PU-H8IZ-C69E-3IG2-6P6W

但是,我发现此脚本有时会返回少于39个字符的字符串,其中包含仅包含2或3个字符的块.

21-15-18-5UD1-V471-I158-J23R-M714

我尝试设置一个条件,如果生成的块少于4个字符,则递归地运行blockBuilder(),但这些有缺陷的ID仍将打印到页面.

var alphabet = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";

var alphaArray = alphabet.split(",").map(function(l) {
  return l.toUpperCase()
});

function randomLetter() {
  var index = Math.floor(Math.random() * 26);
  return alphaArray[index];
}

function randomNumber() {
  return Math.floor(Math.random() * 10);
}

function blockBuilder() {
  var block = randomChar() + randomChar() + randomChar() + randomChar();

  if (block.length < 4) {
    blockBuilder(); //recursive check
  }

  return block;
}

function idBuilder() {
  return blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder()


}

function randomChar() {
  return Math.floor(Math.random() * 2) == 0 ? randomLetter() : randomNumber();
}

for (var i = 0; i < 100; i++) {
  var v = idBuilder();

  document.write(v + "<br>");

}
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?谢谢.

T.J*_*der 6

这是因为你的randomNumber函数返回一个数字,而不是一个数字.如果你连续两个,它们被加在一起,而不是连接在一起.例如,在这一行:

var block = randomChar() + randomChar() + randomChar() + randomChar();
Run Code Online (Sandbox Code Playgroud)

...假设第一个调用返回2,第二个返回3,第三个返回4,第四个返回"X".那是:

var block = 2 + 3 + 4 + "X";
Run Code Online (Sandbox Code Playgroud)

...... "9X"不是"234X".这将在第一次和第二次调用(至少)返回数字时发生.

转换为字符串解决了它:

function randomNumber() {
  return String(Math.floor(Math.random() * 10));
}
Run Code Online (Sandbox Code Playgroud)

例:

var alphabet = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";

var alphaArray = alphabet.split(",").map(function(l) {
  return l.toUpperCase()
});

function randomLetter() {
  var index = Math.floor(Math.random() * 26);
  return alphaArray[index];
}

function randomNumber() {
  return String(Math.floor(Math.random() * 10));
}

function blockBuilder() {
  var block = randomChar() + randomChar() + randomChar() + randomChar();

  if (block.length < 4) {
    blockBuilder(); //recursive check
  }

  return block;
}

function idBuilder() {
  return blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder()


}

function randomChar() {
  return Math.floor(Math.random() * 2) == 0 ? randomLetter() : randomNumber()
}

for (var i = 0; i < 100; i++) {
  var v = idBuilder();

  document.write(v + "<br>");

}
Run Code Online (Sandbox Code Playgroud)


旁注:这if (block.length < 4)是不必要的,检查不可能是真的.(只是blockBuilder再次打电话而不用其结果做任何事情都不会有帮助.)

附注2:你的randomChar功能选择一个字母或一个数字(数字),给每个人50/50的机会.这减少了你的弦乐的独特性,只有一半的时间限制在10个选择.您可能会考虑做Barmar所询问的事情,只是将数字添加到整个列表中,这将使A实现更简单,并且B)在36个选项中更均匀地传播数据.

例如:

var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".split("");

function blockBuilder() {
  var block = randomChar() + randomChar() + randomChar() + randomChar();
  return block;
}

function idBuilder() {
  return blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder() + "-" + blockBuilder()
}

function randomChar() {
  return chars[Math.floor(Math.random() * chars.length)];
}

for (var i = 0; i < 100; i++) {
  var v = idBuilder();
  document.write(v + "<br>");
}
Run Code Online (Sandbox Code Playgroud)