【问题标题】:Get random item from array, within a for loop, then remove from array在for循环中从数组中获取随机项,然后从数组中删除
【发布时间】:2012-11-21 00:02:16
【问题描述】:

我正在编写一个脚本,onload 会将一个类添加到 12 个 DIV 中的随机 4 个,然后从数组中删除 DIV 的 ID。

我有一个包含所有 12 个 DIV ID 的数组设置。

有时当我重新加载页面时,4 个 DIV 具有该类,而其他时候只有 3 个 DIV 具有该类。

有点坚持为什么会这样。 我注释掉了从数组代码中删除,看看这是否是问题所在,但仍然是同样的问题。

这是我的代码:

//Randomize Which Shoes Are Positive And Negative
function randomizeShoes(){
    allGroundShoes = new Array('ground_black_1','ground_black_2','ground_brown_1','ground_brown_2','ground_clown_1','ground_clown_2','ground_disco_1','ground_disco_2','ground_moccasins_1','ground_moccasins_2','ground_red_1','ground_red_2');
    for(var i=0; i < 4; i++){
        randomAllGroundShoes = allGroundShoes[Math.floor(Math.random() * allGroundShoes.length)];
        $('#'+randomAllGroundShoes+'').addClass('shoeNegitive');
        //randomShoeID = allGroundShoes.indexOf('randomAllGroundShoes');
        //if(randomShoeID != -1){ allGroundShoes.splice(randomShoeID, 1); }
    }
}

【问题讨论】:

  • Math.floor(Math.random() * allGroundShoes.length) 必须是 Math.floor(Math.random() * allGroundShoes.length - 1),因为数组从 0 开始。长度将返回 12 但 allGroundShoes[12] 将不存在,因为最后一项将是 allGroundShoes[11],因为它从 @ 开始987654327@.
  • @MrXenotype 似乎是这样,但Math.random() 返回一个从 0.0 到小于 1 的浮点数(即 0 包含到 1 排除)。详情请参阅MDN page

标签: javascript jquery arrays random array-splice


【解决方案1】:

当您删除找到的元素时,您传入的是字符串文字而不是变量名:

allGroundShoes.indexOf('randomAllGroundShoes');

由于没有元素'randomAllGroundShoes',因此永远不会找到该元素,也不会从数组中删除任何元素。

应该是:

allGroundShoes.indexOf(randomAllGroundShoes);

但是,你不止一次地做同样的事情。你根本不需要检查allGroundShoes.indexOf()。您可以将随机数存储在变量中并再次引用它。但是,即使这也超出了您的需要。只需致电splice() 即可获得您的价值:

randomAllGroundShoes = allGroundShoes.splice(
    Math.floor(Math.random() * allGroundShoes.length), 1)[0];
$('#'+randomAllGroundShoes).addClass('shoeNegitive');

这样,您只需一步即可检索您的值并将其从数组中删除 - 无需额外查找。

jsfiddle.net/kRNTg

【讨论】:

  • 正如我所说的 :-) 但是我建议使用一个变量作为索引而不是这个冗长的单行(为什么要使用 randomAllGroundShoes,我们可以将随机选择移到jQuery 选择)...
【解决方案2】:

我相信您的删除代码是问题所在。尝试将最后两行注释掉的行更改为:

randomShoeID = allGroundShoes.indexOf(randomAllGroundShoes);
if(randomShoeID != -1){ allGroundShoes = allGroundShoes.splice(randomShoeID, 1); }

【讨论】:

  • 在此操作之后,allGroundShoes 将包含 1 个元素 - 刚刚找到的元素。
  • @gilly3 很好,先生。我忘记了 splice 返回删除的数组元素。
【解决方案3】:

同样的数字可能会生成两次。

在这种情况下,您必须有一个检查机制是否该号码已被使用。

您可以做的是生成一个由 4 个唯一随机数组成的数组并遍历它来设置类。

var unqiue_arr = []
while(arr.length < 8){
  var randomnumber=Math.floor(Math.random()*12)
  var found=false;
  for(var i=0;i<3;i++){
    if(unqiue_arr[i]==randomnumber){found=true;break}
  }
  if(!found)unqiue_arr[unqiue_arr.length]=randomnumber;
}

【讨论】:

  • 你会这么想,嘿?但是Math.random() 永远不会给出 1.0 的结果。详情请见this MDN link
  • @GregL +1 实际上是的,在这种情况下应该是第二个原因。编辑我的答案
  • 他已经从数组中删除了元素(或者至少,他正在尝试)。这足以防止重复 - 只要它有效。这种嵌套循环的方法效率很低。
【解决方案4】:

带有注释行的代码存在以下问题,即当未删除项目时,它们可能会被随机选择两次或更多次。

您注释掉的行也有同样的问题。您确实搜索了allGroundShoes.indexOf('randomAllGroundShoes');,它(作为字符串而不是变量)从未包含在数组中。

改用此代码:

function randomizeShoes(){
    allGroundShoes = ['ground_black_1','ground_black_2','ground_brown_1','ground_brown_2','ground_clown_1','ground_clown_2','ground_disco_1','ground_disco_2','ground_moccasins_1','ground_moccasins_2','ground_red_1','ground_red_2'];
    for (var i=0; i<4; i++){
        var randomShoeID = Math.floor(Math.random() * allGroundShoes.length);
        var randomAllGroundShoes = allGroundShoes[randomShoeID];
        $('#'+randomAllGroundShoes+'').addClass('shoeNegitive');
        allGroundShoes.splice(randomShoeID, 1);
    }
}

无需搜索您已经知道的项目的索引,也无需检查-1,因为您知道该项目包含在您刚刚从中取出它的数组中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-04
    • 2017-09-12
    • 2021-03-03
    • 2013-04-28
    • 2021-06-17
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    相关资源
    最近更新 更多