我有一个这样的数组:

var arr1 = ["a", "b", "c", "d"];

我如何随机化/打乱它?


当前回答

Fisher Yates的另一个实现,使用严格模式:

function shuffleArray(a) {
    "use strict";
    var i, t, j;
    for (i = a.length - 1; i > 0; i -= 1) {
        t = a[i];
        j = Math.floor(Math.random() * (i + 1));
        a[i] = a[j];
        a[j] = t;
    }
    return a;
}

其他回答

首先,在这里查看javascript中不同排序方法的视觉比较。

其次,如果您快速查看上面的链接,您会发现与其他方法相比,随机顺序排序的性能似乎相对较好,同时实现起来非常简单和快速,如下所示:

function shuffle(array) {
  var random = array.map(Math.random);
  array.sort(function(a, b) {
    return random[array.indexOf(a)] - random[array.indexOf(b)];
  });
}

编辑:正如@gregers所指出的,比较函数是用值而不是索引来调用的,这就是为什么需要使用indexOf的原因。注意,由于indexOf在O(n)时间内运行,此更改使代码不太适合较大的数组。

对于我们这些不是很有天赋但能接触到洛达什奇迹的人来说,有一种叫做洛达什·舒夫的东西。

var shuffle = function(array) {
   temp = [];
   originalLength = array.length;
   for (var i = 0; i < originalLength; i++) {
     temp.push(array.splice(Math.floor(Math.random()*array.length),1));
   }
   return temp;
};

我想分享解决这个问题的百万种方法之一=)

function shuffleArray(array = ["banana", "ovo", "salsicha", "goiaba", "chocolate"]) {
const newArray = [];
let number = Math.floor(Math.random() * array.length);
let count = 1;
newArray.push(array[number]);

while (count < array.length) {
    const newNumber = Math.floor(Math.random() * array.length);
    if (!newArray.includes(array[newNumber])) {
        count++;
        number = newNumber;
        newArray.push(array[number]);
    }
}

return newArray;

}

我自己写了一个shuffle函数。这里的区别是它永远不会重复一个值(检查代码):-

function shuffleArray(array) {
 var newArray = [];
 for (var i = 0; i < array.length; i++) {
     newArray.push(-1);
 }

 for (var j = 0; j < array.length; j++) {
    var id = Math.floor((Math.random() * array.length));
    while (newArray[id] !== -1) {
        id = Math.floor((Math.random() * array.length));
    }

    newArray.splice(id, 1, array[j]);
 }
 return newArray; }