0

在这里,我有一个元素数量未定义的数组。我试图打印这个数组的随机元素并剪切它。这是我的代码。

function rand(min, max){
   return (Math.floor(Math.random() * (max - min + 1)) + min).toFixed(0);
}
$('#do').click(function(){
    var count = chamarr.length;
    var num = 0;
    if (count == 1) {
      $('#output').html('Nothing can found');
    } else {
      num = rand(1,chamarr.length);
      $('#output').html(chamarr[num]);
      chamarr.splice(num,1);
    }
 });

当我记录一个数组被切割时,我看到总是好的,但有时元素没有被切割!

4

3 回答 3

7

我的猜测是问题出在您的randnum方法上:

function rand(min, max){
   return (Math.floor(Math.random() * (max - min + 1)) + min).toFixed(0);
}

相信这会给你一个范围内的价值[min, max]——包括两端。(实际上,它会为您提供该值的字符串版本作为toFixed返回字符串,但是当您稍后使用它时,它会被强制转换为数字。)

现在你这样称呼它:

num = rand(1,chamarr.length);

因此,如果数组的长度为 6 个元素,您将获得 range 中的值[1, 6]。但是随后您将尝试采用chamarr[num]- 有效索引的范围是[0, 5]因为数组是基于 0 的。如果您尝试使用元素 6,那将给您undefined- 但是在元素 6 处拼接将无济于事。

我会将您的rand方法更改为在上限处独占,如下所示:

function rand(min, max) {
   return (Math.floor(Math.random() * (max - min)) + min).toFixed(0);
}

然后这样称呼它:

num = rand(0, chamarr.length);

这将为索引和拼接提供正确范围内的值。

编辑:回应评论等:

  • 可能值得删除该功能的toFixed(0)一部分rand;毕竟,你并不真正想要一个字符串。这实际上并不是以前错误的一部分,但它通常更干净:

    function rand(min, max) {
       return Math.floor(Math.random() * (max - min)) + min;
    }
    
  • 您可能还需要一个使0下限隐式的函数版本

  • 如果您不打算在代码中的其他任何地方使用随机数,您可以内联Math.floor()/Math.random()调用而不是使用单独的函数,但我个人希望让它们远离只想得到的“逻辑”代码一个随机数并使用它。
  • 我改变这个函数的原因是,在计算机科学中拥有一个独占的上限更为常见——它通常与集合之类的 0 索引一起使用。您通常会编写for包含下限和互斥下限等的循环。
于 2012-07-07T08:20:13.363 回答
2

问题是num索引超出范围。你应该做这个:

num = rand(0, chamarr.length - 1);
于 2012-07-07T08:20:15.610 回答
0

您可以简化逻辑:

function rand(max) {
  return Math.round( Math.random() * max ) % max;
}
var arr = [1, 2, 3, 4],
    len = arr.length,
    num = rand(len);

if ( len === 1 ) {
    // Do your "Nothing here" output
}
else {
    arr.splice(num, 1);
    // etc, etc, etc...
}
于 2012-07-07T08:27:05.923 回答