Выбор нескольких случайных элементов массива в JavaScript
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Для извлечения случайных элементов из массива можно использовать метод перемешивания Фишера – Йетса и затем обрезать массив до нужной длины:
function getRandomElements(arr, n) {
let w = arr.length, t, i;
// Применяем алгоритм Фишера – Йетса
while (w) {
i = Math.floor(Math.random() * w--);
t = arr[w];
arr[w] = arr[i];
arr[i] = t;
}
// Возвращаем первые n элементов
return arr.slice(0, n);
}
// Пример использования:
const randomItems = getRandomElements([1, 2, 3, 4, 5, 6], 3);
console.log(randomItems); // Пример результата: [4, 1, 5]
Обратите внимание, что при использовании тасования полезно ограничить его только до индекса n
, чтобы в результате не оказались элементы, которых просто нет в массиве.
Эффективное перемешивание для больших массивов
При работе с большими массивами интенсивное перемешивание может снизить производительность. В этом случае целесообразно перемешивать элементы только до индекса n
:
function efficientRandomElements(arr, count) {
let result = new Array(count),
len = arr.length,
taken = new Array(len);
if (count > len)
throw new RangeError("efficientRandomElements: количество запрашиваемых элементов превышает их количество в массиве");
while (count--) {
let x = Math.floor(Math.random() * len);
result[count] = arr[x in taken ? taken[x] : x];
taken[x] = --len in taken ? taken[len] : len;
}
return result;
}
Компактный код с помощью lodash
Любители практичной и простой реализации, пользующиеся библиотекой lodash, могут выполнить выбор элементов следующим образом:
const _ = require('lodash');
let randomElems = _.sampleSize([1, 2, 3, 4, 5, 6], 3);
Гарантированное отсутствие дубликатов элементов
Если требуется набор уникальных элементов, использование Множества (Set) или метода _.sampleSize
из lodash обеспечит уникальный выбор:
function uniqueFlowers(arr, n) {
let resultSet = new Set();
while (resultSet.size < n) {
resultSet.add(arr[Math.floor(Math.random() * arr.length)]);
}
return Array.from(resultSet);
}
// Альтернативный подход — использование lodash:
let uniqueBlooms = _.sampleSize([1, 2, 3, 4, 5, 6], 3);
Будьте осторожны при запросе большого количества элементов
Запрашивайте разумное количество элементов, чтобы избежать ситуации, когда клиент хочет получить больше данных, чем есть в наличии. Программа может либо вернуть все доступные элементы массива, либо выдать предупреждение:
function cautionaryTale(arr, n) {
if( n > arr.length ) {
console.warn("Запрошено больше элементов, чем доступно. Возвращаются все элементы массива.");
return arr;
}
return getRandomElements(arr, n);
}
Визуализация
Можно представить процесс выбора случайных элементов как лотерею:
Исходный массив: [🔑, 🎩, 🐇, 🎓, 🎈, 📚]
Требуется выбрать: 3 случайных элемента
Процесс можно сравнить с тем, как если бы мы крутили барабан и вытаскивали 3 счастливых значка:
Запускаем... 🥁🌀
И выбираем: [🎓, 🐇, 🔑]
В коде это будет выглядеть так:
function getRandomElements(arr, count) {
let shuffled = [...arr].sort(() => 0.5 – Math.random());
return shuffled.slice(0, count);
}
Применение данной функции даст вам интересные и непредсказуемые результаты:
getRandomElements([🔑, 🎩, 🐇, 🎓, 🎈, 📚], 3)
// Возможный результат: [🎈, 🔑, 🎓]
Справедливый выбор при работе в условиях высокой нагрузки
При работе с большим объемом данных или когда нужна максимальная производительность, лучше свести к минимуму число перемешиваний. При этом важно обеспечить честность выбора, гарантируя равные шансы для всех элементов.
Полезные материалы
- Math.random() — JavaScript | MDN — документация метода
Math.random()
на MDN. - Get a random item from a JavaScript array — Stack Overflow — общение программистов об оптимальных способах извлечения случайных элементов из массива на Stack Overflow.
- Методы массивов — подробное описание разных методов обработки массивов, включая
slice
, на сайте learn.javascript.ru. - how can I shuffle an array? — Stack Overflow — обсуждение разных способов перемешивания элементов массива на Stack Overflow.
- JavaScript — N random elements in array — 30 seconds of code — краткое руководство о том, как выбрать нескольких случайных элементов из массива на 30 seconds of code.
- Array.prototype.slice() — JavaScript | MDN — подробности метода
Array.prototype.slice()
на MDN.