Escribí un código para mi bot discord.js. El bot selecciona aleatoriamente una cita de la lista y la envía al canal. Me gustaría evitar que las comillas se repitan, pero no estoy seguro de cómo.
const Discord = require('discord.js'); require('dotenv').config(); const client = new Discord.Client(); const config = require("./config.json"); const quotes = [ { id: "1", quote: "This is quote 1" }, { id: "2", quote: "This is quote 2" }, { id: "3", quote: "This is quote 3" }, { id: "4", quote: "This is quote 4" }, { id: "5", quote: "This is quote 5" }, ]; client.on('message', (msg) => { if (msg.content.startsWith("T!quote")) { const random = quotes[Math.floor(Math.random() * quotes.length)]; msg.channel.send(`${random.quote}` + `Quote #: ` + `${random.id}`); } });Revuelva la matriz... devuelva cada valor en orden... cuando haya llegado al final, vuelva a mezclar, enjuague y repita
const shuffler = inArray => { const array = [...inArray]; let index = array.length; return () => { if (index === array.length) { // (re-)shuffle while(index) { const j = Math.floor(Math.random() * (index--)); if (index !== j) { [array[index], array[j]] = [array[j], array[index]]; } } } return array[index++]; } }; const quotes = [ { id: "1", quote: "This is quote 1" }, { id: "2", quote: "This is quote 2" }, { id: "3", quote: "This is quote 3" }, { id: "4", quote: "This is quote 4" }, { id: "5", quote: "This is quote 5" }, ]; const getNextQuote = shuffler(quotes); /* client.on('message', (msg) => { if (msg.content.startsWith("T!quote")) { const random = getNextQuote(); msg.channel.send(`${random.quote} Quote #: ${random.id}`); } }); */ for (let n = 0; n < 13; n++) { const random = getNextQuote(); console.log(`${random.quote} Quote #: ${random.id}`); }Nota: esto no siempre evitará dos comillas idénticas seguidas, ya que podría haber
cuando la matriz se vuelve a barajar: puede agregar algo de lógica para verificar cuál era el último elemento en la matriz antes de barajar, y asegurarse de que no sea el primer elemento de la matriz después de la baraja
Una forma trivial de hacer esto sería "rotar" la matriz en uno, por ejemplo, desplazando el primer elemento de la matriz y empujándolo hasta el final.
if (index === array.length) { const lastItem = array[index - 1]; // prevent repetition while(index) { const j = Math.floor(Math.random() * (index--)); if (index !== j) { [array[index], array[j]] = [array[j], array[index]]; } } // prevent repetition if (array[lastItem] === array[0]) { array.push(array.shift()); } }Puede utilizar una estructura de datos de conjunto hash para evitar duplicados.
var set = new Set(); client.on('message', (msg) => { if (msg.content.startsWith("T!quote")) { let random = quotes[Math.floor(Math.random() * quotes.length)]; while(set.has(random[0].id)){ random = quotes[Math.floor(Math.random() * quotes.length)]; } msg.channel.send(`${random.quote}` + `Quote #: ` + `${random.id}`); set.add(random[0].id) } });Pero al usar la función aleatoria, es posible elegir el mismo elemento una y otra vez, y el ciclo funcionará sin parar. Digamos que tiene un conjunto limitado de mensajes, por lo que cada vez que lo agrega al conjunto, debe reducir su conjunto de comillas. Por lo tanto, almacenar citas en algún lugar y luego eliminar elementos de la matriz de copia también es una solución.