Выборка с помощью "Math.random" иногда выбирает повторяющиеся элементы из массива.
Я пытаюсь передать элементы в голосовом канале случайным образом элементам в содержимом сообщения. но он снова выбирает того же человека. как я могу предотвратить это? также пользователь, который не знает discord.js ppl example = user = ["2222222", "21111112"]
let users = message.member.voiceChannel.members
.filter(y => y.user.id !== message.author.id)
.map(a => a.user.id);
for (var i = 0; i < num; i++) {
var user = users[Math.floor(Math.random() * num)];
console.log(user);
let adi = message.guild.members.get(user);
liste += "" + adi.displayName + " adlı kullanıcının rolü " + rol + "\n";
oyuncular += " <@" + adi.user.id + "> ";
}
2 ответа
Существует два вида методов случайного выбора: "бросок" и "раздача". Бросок может получить одно и то же значение более одного раза, как и при броске кубиков. Раздача приобретает другое значение, как и раздача карт.
Вы используете рулон. Вам нужна сделка. Вам необходимо исключить каждое значение из дальнейшего рассмотрения по мере его выбора.
Допустим, вы заселили свой 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 */
}
Splice - хороший выбор для этого; на двигатель V8 Javascript разработчики упорно трудились, чтобы сделать его как можно более эффективным.
Вы можете проверить это, вставив следующий код в консоль REPL в инструментах разработчика браузера.
(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)
Это упрощение алгоритма перемешивания Фишера-Йейтса (он же Кнут), упомянутого здесь. Этот алгоритм перемешивает все во входном массиве. Но в этом нет необходимости, если вам нужно выбрать только несколько элементов из более длинного массива.
Что такое "число" в вашем примере?
Конечно, сработало бы следующее:
var user = users[Math.floor(Math.random() * users.length)];