Комментарии 3
Можно не делать перестановки, а брать каждый раз случайный номер в уже уменьшенном массиве. Это вроде будет быстрее
Насчет быстрее не знаю, но это ещё и будет правильно, потому что дает истинно равновероятные итоговые перестановки. А в представленном коде получается n^(n-1) исходов, которые довольно хорошо, но не идеально распределяются по n! перестановкам (одно на другое не делится). Собственно, автор почти открыл "тасование Фишера-Йетса", и его ошибка даже упомянута в статье на Википедии.
Классическое тасование Фишера - Йетса (оно же тасование Кнута) обеспечивает лучшую равномерность:
for(let n = arr.length - 1; n > 0; --n) {
let rnd = Math.floor(Math.random() * (n + 1));
[arr[n], arr[rnd]] = [arr[rnd], arr[n]];
}Смысл в том, что ячейка, в которую записываем выбранное случайное значение, не участвует в дальнейшем тасовании.
Источник: https://ru.wikipedia.org/wiki/Тасование_Фишера_—_Йетса#Современный_алгоритм

Генерация колоды карт