/**
* [费舍尔-耶茨洗牌算法](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)
* 原地洗牌实现(直接修改原始数组顺序)
*
* 该算法用于生成集合的随机[排列](https://en.wikipedia.org/wiki/Permutation)。
* 注意:此方法会通过引用直接修改原始数组顺序。
*
* @param {Array} x 包含一个或多个数值的样本集
* @param {Function} [randomSource=Math.random] 可选随机数源,需返回[0,1)区间的数值
* @returns {Array} 原数组x(已洗牌)
* @example
* var x = [1, 2, 3, 4];
* shuffleInPlace(x);
* // x将被洗牌为类似[2, 1, 4, 3]的随机排列
*/
function shuffleInPlace(x, randomSource) {
// 支持传入自定义随机数生成器,例如使用固定种子
// 或第三方库如[random-js](https://www.npmjs.org/package/random-js)
randomSource = randomSource || Math.random;
// 记录当前未洗牌元素的长度
let length = x.length;
// 暂存元素交换的临时变量
let temporary;
// 当前待交换元素的索引
let index;
// 当未洗牌元素存在时进行迭代
while (length > 0) {
// 在未洗牌区间内随机选取索引
// 注意:length--在取值后自减实现区间收缩
index = Math.floor(randomSource() * length--);
// 暂存当前末端元素
temporary = x[length];
// 将随机选取的元素与当前末端元素交换
x[length] = x[index];
x[index] = temporary;
}
return x;
}
export default shuffleInPlace;