Существует два вида методов случайного выбора: «бросок» и «сделка». Бросок может получить одно и то же значение более одного раза, как при броске в кости. Сделка получает другое значение, как при раздаче карт.
Вы используете бросок. Тебе нужна сделка. Вам нужно удалить каждое значение из дальнейшего рассмотрения, когда вы его выберете.
Допустим, вы заполнили свой массив users
, и теперь вы хотите получить из него num
значений. Для этого вы удалили каждый элемент из вашего массива по вашему выбору. Это работа для splice()
.
for (let i = 0; i < num; i++) {
if (users.length <= 0) break
const randex = Math.floor(Math.random() * users.length)
const user = users.splice(randex, 1)[0]
/* do what you want with this user */
}
Соединение - хороший выбор для этого; V8 Javascript Движок Разработчики приложили немало усилий, чтобы сделать его максимально эффективным.
Вы можете проверить это, вставив следующий код в консоль REPL в вашем браузере devtools.
(function deal (k, n) {
function range1(i){return i?range1(i-1).concat(i):[]}
const users = range1(n)
for (let i = 0; i < k; i++) {
if (users.length <= 0) break
const randex = Math.floor(Math.random() * users.length)
const user = users.splice(randex, 1)[0]
console.log (user)
}
})(7, 52)
Это упрощение алгоритма тасования Фишера-Йейтса (он же Кнут), упомянутого здесь . Этот алгоритм перемешивает все во входном массиве. Но в этом нет необходимости, если вам нужно выбрать только несколько элементов из более длинного массива.