# 关于数组乱序的深挖——“感觉一直在写毒代码”

。 @。

## 多个熟悉的场景

``````var numbers = [12,4,16,3];
numbers.sort(function() {
return .5 - Math.random();
});``````

## 有毒的array.sort方法

``var letters = ['A','B','C','D','E','F','G','H','I','J'];``

letters这样一个数组使用array.sort方法进行了10000次乱序处理，并把乱序的每一次结果存储在countings当中。

``````var countings = [
{A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
{A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
{A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
{A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
{A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
{A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
{A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
{A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
{A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0},
{A:0,B:0,C:0,D:0,E:0,F:0,G:0,H:0,I:0,J:0}
];
var letters=['A','B','C','D','E','F','G','H','I','J'];
for (var i = 0; i < 10000; i++) {
var r = ['A','B','C','D','E','F','G','H','I','J'].sort(function() {
return .5 - Math.random();
});
for(var j = 0; j <= 9; j++) {
countings[j][r[j]]++;
}
}
for(var i = 0; i <= 9;i++) {
for(var j = 0;j <= 9;j++) {
document.getElementById('results').rows[i + 1].cells[j + 1].firstChild.data = countings[i][letters[j]];
}
}``````

## array.sort方法底层究竟如何实现？

Chrome v8引擎源码中，可以清晰看到，

v8在处理sort方法时，使用了插入排序和快排两种方案。当目标数组长度小于10时，使用插入排序；反之，使用快排。
Chrome’s v8 uses a combination of InsertionSort and QuickSort. That is, if the array is less than 10 elements in length, it uses an InsertionSort.

## 真正意义上的乱序

``````Array.prototype.shuffle = function() {
var input = this;
for (var i = input.length-1; i >=0; i--) {
var randomIndex = Math.floor(Math.random()*(i+1));
var itemAtIndex = input[randomIndex];
input[randomIndex] = input[i];
input[i] = itemAtIndex;
}
return input;
}
var tempArray = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
tempArray.shuffle();
console.log(tempArray);  ``````

Step1：

Step2：

Step3：

## 自己实现乱序

``````function shuffle (array) {
var copy = [],
n = array.length,
i;
while (n) {
i = Math.floor(Math.random() * array.length);
if (i in array) {
copy.push(array[i]);
delete array[i];
n--;
}
}
return copy;
}``````

``````function shuffle(array) {
var copy = [],
n = array.length,
i;
while (n) {
i = Math.floor(Math.random() * n--);
copy.push(array.splice(i, 1)[0]);
}
return copy;
}``````

``````function shuffle(array) {
var m = array.length,
t, i;
while (m) {
i = Math.floor(Math.random() * m--);
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
}``````

Happy Coding!

PS: