underscore.js 里有一个数组重新随机排序的函数 _.shuffle
:
|
|
函数的算法
- 创建 数组
shuffled = []
,用于保存随机排序后的数组; - 迭代 待排序数组,设定当前迭代索引
index = 0
; - 生成 随机索引
rand
。rand
的值介于[0, index]
; - 添加 元素到
shuffled
数组,值为shuffled[rand]
; - 赋予
shuffle[rand]
当前迭代元素的值
运行过程
假定现有待随机排序数组 array = [1, 2, 3, 4, 5]
,那么第一次迭代的时候情形如下:
|
|
此时,rand
的值只能与 index
的值相等,所以 shuffled
第一个元素取值为待排序数组的第一个元素。
第二次迭代时,假定 rand
随机值为 0
( rand
的值只能在 [0, index]
之间):
|
|
shuffle[1]
被赋值为 shuffle[0]
,shuffle[0]
被赋值为 array[1]
。
最后一次迭代假设此时 rand = 1
,shuffled = [2, 4, 1, 5]
:
|
|
shuffled[4]
将会被赋值为 shuffled[1]
,shuffled[1]
被赋值为 3
。所以 shuffled
最后为 [2, 3, 1, 5, 4]
。
另一种思路
- 迭代 待排序数组;
- 生成 随机索引
rand
,索引的范围为[0 ~ 待排序数组 - 1]
; - 抽取 待排序数组中索引为
rand
的元素,抽取行为改变了待排序数组; - 追加 抽取的元素到结果数组的末尾
|
|
相对于 _.shuffle
,这个方法每个元素在每次迭代过程中就确定下来了,而 _.shuffle
结果数组中每个元素在最后一步完成前都可能改变。