问题:一个数组里有a到z 26个字母,随机抽取字母,不能重复,保证每个字母被抽取到的概率一样。
生成随机数的方法大家都知道Math.random(),关键在于如何去除重复的数。
思路:每次从没有取过的字母中选择一个和最后一位进行对换。
直接结合代码理解:
let swap = arr => {
let result = [];
// 注意了length是从1开始的,所以要arr.length - 1
for(let i = arr.length - 1; i > 0;) {
let index = Math.floor(Math.random()*i)
result.push(arr[index]);
arr[index] = arr[i--];
}
return result
}
第一次循环的时候:
假设index摇到了24,也就是字母y。然后y和最后一位z交换,i - 1
[a,b,c...x, y ,z] -> [a,b,c...x,z, y ]
第二次循环的时候:
此时的i=24,数组中能取到的字母变成了
[a,b,c...x,z] ,y 这个已经抽到过的字母被完美的排除在外