Как перемешать массив
Короткий ответ
Алгоритм Фишера-Йетса идёт с конца и меняет каждый элемент местами со случайным элементом перед ним:
const shuffle = (array) => {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}
return result;
};
const cards = ['A', 'K', 'Q', 'J', '10'];
const shuffled = shuffle(cards);
console.log(shuffled.length, [...shuffled].sort().join(''));Результат:
5 10AJKQЧастая ошибка
Популярный sort(() => Math.random() - 0.5) короче, но перемешивает неравномерно: одни порядки выпадают заметно чаще других. Посчитайте, как часто первый элемент остаётся на месте:
let stays = 0;
for (let i = 0; i < 10000; i++) {
const result = [1, 2, 3, 4, 5].sort(() => Math.random() - 0.5);
if (result[0] === 1) stays++;
}
console.log(stays > 2000 ? 'more often than 1 in 5' : 'about 1 in 5');Результат:
more often than 1 in 5При честном перемешивании первый элемент остаётся на месте примерно в одном случае из пяти.
Функции из этого ответа
- Math.random — Возвращает случайное число от 0 до 1.
- Math.floor — Округляет число вниз до целого.