# 常用的sort打乱数组方法真的有用？

JavaScript 开发中有时会遇到要将一个数组随机排序（shuffle）的需求，一个常见的写法是这样：

```function shuffle(arr) {
arr.sort(function () {
return Math.random() - 0.5;
});
}```

```function shuffle(arr) {
arr.sort(() => Math.random() - 0.5);
}```

### 问题

```let n = 10000;
let count = (new Array(10)).fill(0);

for (let i = 0; i < n; i ++) {
let arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
arr.sort(() => Math.random() - 0.5);
count[arr.indexOf('a')]++;
}

console.log(count);```

```let a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']; // 长度为11
let n = 10000;
let count = (new Array(a.length)).fill(0);

for (let i = 0; i < n; i ++) {
let arr = [].concat(a);
arr.sort(() => Math.random() - 0.5);
count[arr.indexOf('a')]++;
}

console.log(count);```

### 探索

Calling comparefn(a,b) always returns the same value v when given a specific pair of values a and b as its two arguments.

### 解决方案

#### 方案一

```let new_i = {
v: i,
r: Math.random()
};```

```function shuffle(arr) {
let new_arr = arr.map(i => ({v: i, r: Math.random()}));
new_arr.sort((a, b) => a.r - b.r);
arr.splice(0, arr.length, ...new_arr.map(i => i.v));
}

let a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
let n = 10000;
let count = (new Array(a.length)).fill(0);

for (let i = 0; i < n; i ++) {
shuffle(a);
count[a.indexOf('a')]++;
}

console.log(count);```

#### 方案二（Fisher–Yates shuffle）

```-- To shuffle an array a of n elements (indices 0..n-1):
for i from n−1 downto 1 do
j ← random integer such that 0 ≤ j ≤ i
exchange a[j] and a[i]```

```function shuffle(arr) {
let i = arr.length;
while (i) {
let j = Math.floor(Math.random() * i--);
[arr[j], arr[i]] = [arr[i], arr[j]];
}
}```

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

0 条评论

• ### Go语言 实现bitmap

package main import ( "fmt" "math" "math/rand" "unsafe" ) const ...

• ### 你对JavaScript的Array对象了解有多少？

工作中，数组应用非常广泛，菜单、列表、banner图等等都会应用到数组，所以必须对数组的属性和方法非常熟练才OK，下面一起来了解一下。

• ### Excel VBA解读（154）： 数据结构——数组常用操作示例代码

For j = LBound(arr, 2) To UBound(arr, 2)