Tengo una pregunta muy específica. Pasé muchas horas para que funcionara, pero no tuve éxito.
Aquí hay una parte de mi código, cómo se ve ahora:
var mainNames = ["James", "Robert", "John", "Michael", "William", "David", "Peter", "Joseph"]; var genNames = []; var exceptionNames = ["James", "Michael", "David", "Robert"]; for (var i = 0; i < 4; i++) { var idx = Math.floor(Math.random() * names .length); genNames.push(names [idx]); }¿Lo que necesito hacer?
mainNames es la lista principal de la que necesito generar 4 nombres únicos, sin repeticiones. Luego, si en la lista generada se encuentran 2 o más nombres de excepción , repita la generación de la lista de nombres principales hasta que la lista generada final contenga un máximo de 1 nombre de excepción y ninguna repetición de los nombres principales .
Nota: La lista generada también puede contener 0 nombres de excepción , porque la generación es aleatoria y no tiene que generar nombres de excepción como nombres adicionales, porque ya existen en la lista de nombres principales .
¿Cómo imprimo la lista final?
${genNames[0]}, ${genNames[1]}, ${genNames[2]}, ${genNames[3]}Aquí hay algunas posibles salidas correctas:
Santiago, Guillermo, Juan, Pedro
Miguel, Guillermo, Pedro, Juan
Roberto, Juan, Guillermo, Pedro
David, Juan, Guillermo, Pedro
José, Pedro, Juan, Guillermo
Nota: Como puede ver en las posibles salidas correctas, no hay repeticiones de mainNames ni repeticiones de ExceptionNames . Y así es como debería funcionar el código mencionado anteriormente.
¡Gracias por las posibles soluciones/respuestas!
Realice una clasificación aleatoria en la matriz inicial y seleccione los primeros 4 elementos. Luego compare los elementos con la matriz de excepciones y asegúrese de que el recuento sea 1 o menos. Siga repitiendo hasta que se encuentre una solución.
var mainNames = ["James", "Robert", "John", "Michael", "William", "David", "Peter", "Joseph"]; var exceptionNames = ["James", "Michael", "David", "Robert"]; let names = [], count = 4 while(count>1) { names = mainNames.map(i => ({ s: Math.random(), i })).sort((a,b) => as - bs).map(({i})=> i).slice(4); count = names.filter(n => exceptionNames.includes(n)).length; } console.log(names.join(','))Supongo que podría hacerlo así, pero será un poco lento, no sé qué tan grandes serán sus matrices de nombres al final.
let mainNames = [ 'James', 'Robert', 'John', 'Michael', 'William', 'David', 'Peter', 'Joseph', ] let genNames = [] const exceptionNames = ['James', 'Michael', 'David', 'Robert'] let exceptionNameAlreadyIncluded = false while (genNames.length < 4) { // if the variable exceptionNameAlreadyIncluded is true we filter our the exception names // to leave only the "normal" ones const namesToSearch = exceptionNameAlreadyIncluded ? mainNames.filter( (name) => !exceptionNames.some((exName) => exName === name), ) : mainNames // belowe we get random name from our filtered ones push it to the genNamesArray // and we remove it from mainNames array so there is no duplicates const nameToAdd = namesToSearch[getRandomInt(namesToSearch.length)] mainNames = mainNames.filter((name) => name != nameToAdd) genNames = [...genNames, nameToAdd] // if the name we found using random is one of exception names we set our // exceptionNameAlreadyIncluded to true to not include any exception names in future randoms if (exceptionNames.some((name) => name === nameToAdd)) exceptionNameAlreadyIncluded = true } console.log(genNames) function getRandomInt(max) { return Math.floor(Math.random() * max) }Solución más rápida
let mainNames = [ 'James', 'Robert', 'John', 'Michael', 'William', 'David', 'Peter', 'Joseph', ] let genNames = [] const exceptionNames = ['James', 'Michael', 'David', 'Robert'] let exceptionNameAlreadyIncluded = false while (genNames.length < 4) { const nameIndex = getRandomInt(mainNames.length) const isExceptionName = exceptionNames.some( (name) => name === mainNames[nameIndex], ) if (!exceptionNameAlreadyIncluded || !isExceptionName) { genNames.push(mainNames[nameIndex]) } if (isExceptionName) exceptionNameAlreadyIncluded = true mainNames.splice(nameIndex, 1) } console.log(genNames) function getRandomInt(max) { return Math.floor(Math.random() * max) }Para comenzar, parece que tiene algunos errores de sintaxis en su código: "nombres" ya que una variable nunca se crea / inicializa antes de intentar usarla, por ejemplo. Supongo que estaba destinado a ser "mainNames".
Tampoco debe haber espacios entre la variable y las llamadas al método. por ejemplo, 'nombres .longitud' debe ser 'nombres.longitud' y 'nombres [idx]' debe ser 'nombres[idx].
Aparte de eso, le falta alguna forma de verificar que el nombre seleccionado no esté ya en la lista. Una vez que tenga su índice aleatorio, conviértalo en un valor y luego verifique si cumple con los criterios que enumeró antes de continuar (si aún no está en la lista). Hay varias formas de hacerlo, pero es el paso más importante que te estás perdiendo.
Luego, también debe agregar una forma de verificar que sus nombres de excepción aparezcan solo una vez. Una vez más, hay varias formas de hacerlo, pero actualmente falta ese paso por completo.
Si se está atascando con problemas como este, le recomiendo escribir los pasos que debe realizar en pseudocódigo (en comentarios en lenguaje sencillo) antes de saltar directamente al código real. Eso realmente puede ayudar a mantener las cosas en orden.