如何从数组中随机删除一个元素并重复操作直到数组为空

20
我想从一个数组中删除随机项,直到数组为空,使用jQuery或JavaScript。我需要每次控制台输出随机项目。 基本上,我将创建一个元素,并使用给定数组中的随机图像,直到所有图像都被创建。
这是我的尝试,获取随机项并从数组中删除,但它并没有遍历整个数组-我被卡住了。
"load": function(){
    var imgArray = ['brain', 'mitochondria', 'microsope', 'beaker', 'beaker-2', 'scientist', 'cell', 'atom', 'dropper'];
    function randomItem(array){
        var arrayLength = array.length+1;
        console.log(arrayLength);
        for(var i = 0;i<array.length;i++){
            var item = array[Math.floor(Math.random()*array.length)];
            array.pop(item);
            console.log(array);
        }
    }
    randomItem(imgArray);
},

这是我的控制台输出:

10
home.js:12 ["brain", "mitochondria", "microsope", "beaker", "beaker-2", "scientist", "cell", "atom"]
home.js:12 ["brain", "mitochondria", "microsope", "beaker", "beaker-2", "scientist", "cell"]
home.js:12 ["brain", "mitochondria", "microsope", "beaker", "beaker-2", "scientist"]
home.js:12 ["brain", "mitochondria", "microsope", "beaker", "beaker-2"]
home.js:12 ["brain", "mitochondria", "microsope", "beaker"]
3个回答

40

函数Array.prototype.pop()会将一个元素从数组的最后移除。因此,在这种情况下,您需要使用Array.prototype.splice(index,cnt)

for(var i = array.length-1;i>=0;i--){
  array.splice(Math.floor(Math.random()*array.length), 1);
  console.log(array);
}

既然我们要修改数组,我们就必须以相反的方式遍历它,这样索引才不会被折叠。


非常感谢!我一定会深入研究数组文档。 - Travis Michael Heller
@TravisMichaelHeller 很高兴能帮忙! :) - Rajaprabhu Aravindasamy

13
只需在长度大于零的情况下创建随机索引并进行拼接。
var data = ["brain", "mitochondria", "microsope", "beaker", "beaker-2", "scientist", "cell", "atom"];

while (data.length) {
    document.write(data.splice(data.length * Math.random() | 0, 1)[0] + '<br>');
}


1
谢谢你提供另一种选择。我没有考虑使用while循环,现在想想这非常有道理。 - Travis Michael Heller

6

Array.prototype.pop 从数组中移除最后一个元素,而不是特定的元素。要删除特定索引处的元素,可以使用Array.prototype.splice(请参见:如何在JavaScript中从数组中删除特定元素?)。

你还有一个问题是for(var i = 0;i<array.length;i++),因为array.length在你删除一个项时会发生变化,所以你只能遍历一半的数组,你可以反向循环for ( var i = array.length; i--; ),这样array.length只会在第一次迭代之前被评估一次,或者你可以使用while循环while( array.length )

将你的循环更改为:

while( array.length ) {
    var index = Math.floor( Math.random()*array.length );
    console.log( array[index] ); // Log the item
    array.splice( index, 1 ); // Remove the item from the array
}

谢谢您抽出时间来帮忙。我刚告诉尼娜,while循环是我正在寻找的更好的功能选项。 - Travis Michael Heller
刚看到你的更新,谢谢你的解释。从未考虑过反向循环。有一段时间没有与数组打交道了,但显然我需要重新阅读它们,因为我缺乏知识。 - Travis Michael Heller
@TravisMichaelHeller 你也可以像以前一样向前循环,但首先将数组长度放入变量中:var numItems = array.length; 然后 for(var i = 0;i<numItems;i++){,因为当你删除元素时,array.length会改变,但变量不会受到影响。 - Paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接