在PHP中有个函数shuffle,它的作用是将数组打乱顺序。underscore实现了相同功能的同名函数,它采用了Fisher–Yates Shuffle算法。

_.shuffle = function(obj) {
    // 对象也转成数组处理,所以我将这个方法放到了数组而不是集合
    var set = isArrayLike(obj) ? obj : _.values(obj);
    var length = set.length;

    var shuffled = Array(length);
    for (var index = 0, rand; index < length; index++) {
        rand = _.random(0, index);

        // 遍历时 与之前的随机元素交换
        if (rand !== index) shuffled[index] = shuffled[rand];
        huffled[rand] = set[index];
    }
    return shuffled;
};

这个算法可以这么理解:遍历数组,将其与该元素之前的随机元素交换,这样的得到的新数组就是乱序排列的了。这个算法的时间复杂度是O(n),因为只循环一次。

在phpjs这个项目中,作者使用了sort方法:

valArr.sort(function () {
    return 0.5 - Math.random()
})

这个算法看起来很巧妙,但是算法是有问题的。这篇文章指出,用 JavaScript 内置的排序算法(快排、冒泡、插入)这么排序,通常肯定是不完全随机的。从时间复杂度上,也是underscore的最好,因为即使是快速排序,其时间复杂度也是O(nlogn)。

results matching ""

    No results matching ""