使用array.splice()来混乱一个deck数组

时间:2012-05-23 10:48:13

标签: javascript arrays

我正在尝试使用Card随机将newDeck个对象的牌组变为Cardarray.splice()个对象数组。我想我的问题可能与变量范围有关,也可能是对array.splice()的误解。

var deck = [new Card(), new Card(), new Card(), new Card(), new Card(), new Card()];
var newDeck = [];
var shuffle = function(){
    var i = "";
    for (i = 0; i < deck.length; i++){      
        newDeck[i] = deck.splice(Math.floor(Math.random() * deck.length, 1));
}    
};

shuffle();

有没有更好的方法来洗牌?

3 个答案:

答案 0 :(得分:2)

是的,对array.splice()存在误解。阅读docs:它将返回已移除元素的数组,在您的情况下使用一张卡:[<object Card>]。另外,对于deck.splice(Math.floor(Math.random() * deck.length, 1))1(我想应该删除多少张卡片)是Math.floor的参数,而不是splice - 您将删除所有元素后指数。所以,你似乎想要:

function shuffle(deck) {
    var newDeck = [];
    for (var i = 0; i < deck.length; i++)    
        newDeck[i] = deck.splice(Math.floor(Math.random() * deck.length), 1)[0];
    return newDeck;
}    
shuffle([new Card(), new Card(), new Card(), new Card(), new Card(), new Card()]);

您已经要求其他方式进行随机播放:您可以使用非常常见的

deck.sort(function(a, b){ return 0.5-Math.random(); })

或来自underscore.js的算法:

function shuffle(deck) {
    var newDeck = [];
    for (var i = 0; i < deck.length; i++) {    
        var rand = Math.floor(Math.random() * (i + 1));  
        newDeck[i] = newDeck[rand];
        newDeck[rand] = deck[i];
    }
    return newDeck;
}  

答案 1 :(得分:0)

撤消for周期:

for (i = deck.length - 1; i >= 0; i--)
    newDeck.push(deck.splice(Math.floor(Math.random() * deck.length))[0]);

您遇到的问题是每次循环deck.lengthdeck.splice都会减少。或者,您可以在运行脚本之前将deck.length保存在单独的变量中:

var length = deck.length;
for (i = 0; i < length; i++){      
    newDeck[i] = deck.splice(Math.floor(Math.random() * deck.length))[0];

在循环中,您必须使用deck.length

注意:Math.floor只接受一个参数。什么是“,1”应该是什么?初始化i = ""毫无意义,因为该值未被使用。只需添加var i;

修改:修复了Array.splice返回值的缺失点。

答案 2 :(得分:0)

您也可以使用underscore.js中的Array#shuffle方法,以防您在此情况下不想重新发明轮子;)