Estoy tratando de elegir dos nombres al azar y sumarlos. Cada vez que se elige el nombre, debe eliminarse de la matriz. La función debe ejecutarse hasta que la matriz esté vacía. La salida debe ser todos los nombres que se emparejaron en una cadena o matriz.
var names = ['Ben', 'Mike', 'Sally', 'Joe', 'Bob', 'Sam', 'Carl', 'Frank'] //var to pick two random names from an array function pickTwo(arr) { let random = Math.floor(Math.random() * arr.length); let random2 = Math.floor(Math.random() * arr.length); while (random === random2) { random2 = Math.floor(Math.random() * arr.length); } //remove random and random2 from array //run untill there are no more names in the array while (arr.length > 0) { arr.splice(random, 1); arr.splice(random2, 1); return [arr[random], arr[random2]]; } } console.log(pickTwo(names)); console.log(names);Primero asegúrese de eliminar los 2 nombres que seleccionó al azar de la matriz. La función que tiene no hace esto porque la variable arr de la que se eliminan los nombres es local para esa función. Considere usar la variable global groovy que se inicia antes de la función, o devolver la variable arr desde la función y luego enviarla nuevamente. Después de eso, simplemente tienes que hacer un bucle while que ejecute la función pickTwo hasta que no quede nada en Groovy.
var array = []; while(groovy.length>1){ array.push(pickTwo(groovy)); }Necesita obtener nuevos números aleatorios cada vez que pasa por el bucle while (arr.length > 0) . De lo contrario, sus índices aleatorios pueden estar fuera de la matriz después de empalmar y obtener undefined .
Debe empujar cada par de números seleccionados durante el ciclo a otra matriz y devolver esa matriz como el resultado final.
Además, cuando realiza el primer empalme, todos los índices se desplazan random hacia abajo. Si random2 es más alto que random , empalmará el elemento incorrecto. Debes empalmar el superior primero.
Después de empalmar, arr[random] y arr[random2] no se refieren a los elementos que se seleccionaron, ya que los eliminó de la matriz. splice() devuelve los elementos eliminados, debe usar ese resultado.
Una forma más sencilla de hacer todo esto sería barajar la matriz. Luego solo obtenga cada par de elementos secuenciales.
var names = ['Ben', 'Mike', 'Sally', 'Joe', 'Bob', 'Sam', 'Carl', 'Frank'] //var to pick two random names from an array function pickTwo(arr) { let result = []; while (arr.length > 0) { let random = Math.floor(Math.random() * arr.length); let random2 = Math.floor(Math.random() * arr.length); while (random === random2) { random2 = Math.floor(Math.random() * arr.length); } //remove random and random2 from array //run untill there are no more names in the array let val1, val2; if (random < random2) { val2 = arr.splice(random2, 1)[0]; val1 = arr.splice(random, 1)[0]; } else { val1 = arr.splice(random, 1)[0]; val2 = arr.splice(random2, 1)[0]; } result.push([val1, val2]); } return result; } console.log(pickTwo(names)); console.log(names);Algunos problemas en su código:
Cuando random y random2 son tales que random + 1 == random2 y random2 == arr.length - 1 , entonces el segundo splice no tendrá efecto, ya que el tamaño de la matriz ya se redujo.
A medida que return al cuerpo del ciclo while , nunca habrá una segunda iteración de ese ciclo.
Yo sugeriría tomar un enfoque diferente:
function shuffle(a) { var j, x, i; for (i = a.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); x = a[i]; a[i] = a[j]; a[j] = x; } return a; } function pickTwo(arr) { arr = shuffle([...arr]); return Array.from({length: arr.length >> 1}, (_, i) => arr.slice(i*2, i*2+2) ); } var names = ['Ben', 'Mike', 'Sally', 'Joe', 'Bob', 'Sam', 'Carl', 'Frank']; console.log(pickTwo(names));