Выборка с помощью "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)];
Другие вопросы по тегам