Javascript al azar en la matriz sin repetición

Así que estoy tratando de aleatorizar las preguntas pero seguí fallando. Intenté usar este código para agregar, pero hay algunos problemas con él. Cambié currentQuestion a randomQuiz y funcionó, pero nuevamente hay problemas que debían solucionarse.

var randomQuiz = Math.floor(Math.random()*quiz.length); 

archivo .js

  var quiz = [{ "question": "What is the full form of IP?", "choices": ["Internet Provider", "Internet Port", "Internet Protocol"], "correct": "Internet Protocol" }, { "question": "Who is the founder of Microsoft?", "choices": ["Bill Gates", "Steve Jobs", "Steve Wozniak"], "correct": "Bill Gates" }, { "question": "1 byte = ?", "choices": ["8 bits", "64 bits", "1024 bits"], "correct": "8 bits" }, { "question": "The C programming language was developed by?", "choices": ["Brendan Eich", "Dennis Ritchie", "Guido van Rossum"], "correct": "Dennis Ritchie" }, { "question": "What does CC mean in emails?", "choices": ["Carbon Copy", "Creative Commons", "other"], "correct": "Carbon Copy" } , { "question": "wsxwsxwsxwsxwsxwsx?", "choices": ["wsx", "edc", "qaz"], "correct": "wsx" } , { "question": "qazqazqazqazqazqaz?", "choices": ["qaz", "wsx", "edc"], "correct": "qaz" } , { "question": "asdasdasdasdasdasd?", "choices": ["asd", "qwe", "zxc"], "correct": "asd" } , { "question": "zxczxczxczxczxczxc?", "choices": ["zxc", "asd", "qwe"], "correct": "zxc" } , { "question": "qweqweqweqweqweqwe?", "choices": ["qwe", "asd", "zxc"], "correct": "qwe" }]; // define elements var content = $("content"), questionContainer = $("question"), choicesContainer = $("choices"), scoreContainer = $("score"), submitBtn = $("submit"); // init vars var currentQuestion = 0, score = 0, askingQuestion = true; function $(id) { // shortcut for document.getElementById return document.getElementById(id); } function askQuestion() { var choices = quiz[currentQuestion].choices, choicesHtml = ""; // loop through choices, and create radio buttons for (var i = 0; i < choices.length; i++) { choicesHtml += "" + " 
"; } // load the question questionContainer.textContent = "Q" + (currentQuestion + 1) + ". " + quiz[currentQuestion].question; // load the choices choicesContainer.innerHTML = choicesHtml; // setup for the first time if (currentQuestion === 0) { scoreContainer.textContent = "Score: 0 right answers out of " + quiz.length + " possible."; submitBtn.textContent = "Submit Answer"; } } function checkAnswer() { // are we asking a question, or proceeding to next question? if (askingQuestion) { submitBtn.textContent = "Next Question"; askingQuestion = false; // determine which radio button they clicked var userpick, correctIndex, radios = document.getElementsByName("quiz" + currentQuestion); for (var i = 0; i < radios.length; i++) { if (radios[i].checked) { // if this radio button is checked userpick = radios[i].value; } // get index of correct answer if (radios[i].value == quiz[currentQuestion].correct) { correctIndex = i; } } // setup if they got it right, or wrong var labelStyle = document.getElementsByTagName("label")[correctIndex].style; labelStyle.fontWeight = "bold"; if (userpick == quiz[currentQuestion].correct) { score++; labelStyle.color = "green"; } else { labelStyle.color = "red"; } scoreContainer.textContent = "Score: " + score + " right answers out of " + quiz.length + " possible."; } else { // move to next question // setting up so user can ask a question askingQuestion = true; // change button text back to "Submit Answer" submitBtn.textContent = "Submit Answer"; // if we're not on last question, increase question number if (currentQuestion < quiz.length - 1) { currentQuestion++; askQuestion(); } else { showFinalResults(); } } } function showFinalResults() { content.innerHTML = "

You've complited the quiz!

" + "

Below are your results:

" + "

" + score + " out of " + quiz.length + " questions, " + Math.round(score / quiz.length * 100) + "%

"; } window.addEventListener("load", askQuestion, false); submitBtn.addEventListener("click", checkAnswer, false);

archivo .html

       Quiz app      

Quiz app

There will be no points awarded for unanswered questions.

Puede usar una matriz para almacenar la pregunta que se le ha hecho. Verifique la matriz cada vez durante la aleatorización y luego seleccione la pregunta

 var track=new Array(); while(true)//loop until Unique number { var randomQuiz=Math.floor(Math.random()*quiz.length); if(track.indexOf(randomQuiz)==-1)//if you have got your unique random number { track.push(random); break; } } 

Edición : como Stephen P señaló que puede llevar a un problema de rendimiento, eliminar un elemento de la matriz es algo más lógico de hacer como lo sugiere Brent Wagoner .

Simplemente baraja la matriz de preguntas y elige una tras otra. En una versión simplificada:

 var questions = [1,2,3,4,5,6,7,8,9,10]; function shuffle(a) { var cidx, ridx,tmp; cidx = a.length; while (cidx != 0) { ridx = Math.floor(Math.random() * cidx); cidx--; tmp = a[cidx]; a[cidx] = a[ridx]; a[ridx] = tmp; } return a; } function* get_one(arr){ var idx = arr.length; while(idx != 0) yield arr[idx--]; } questions = shuffle(questions); console.log(questions); var nextq = get_one(questions); var alen = questions.length -1; while(alen--) console.log(nextq.next().value); 

No necesita ese generador de lujo, puede obtener uno tras otro en un simple bucle si así lo prefiere.

Dependiendo de lo que esté haciendo al final de la prueba, lo más fácil sería eliminar la pregunta de la matriz una vez que haya sido respondida.

Simplemente barajaría esta lista – luego tomaría las primeras x preguntas:

 var shuffled = quiz.map(x => { return {data: x, srt: Math.random()}}) .sort((a,b) => {return a.srt - b.srt}) .map(x => x.data); 

Tengo otra solución muy pequeña:

Copia la matriz de valores posibles y elimina los que se agregan a la nueva matriz.

 function pickFrom(n, list) { const copy = Array.from(list); return Array.from(Array(n), () => copy.splice(Math.floor(copy.length * Math.random()), 1)[0]); } var quiz = [{ "question": "What is the full form of IP?", "choices": ["Internet Provider", "Internet Port", "Internet Protocol"], "correct": "Internet Protocol" }, { "question": "Who is the founder of Microsoft?", "choices": ["Bill Gates", "Steve Jobs", "Steve Wozniak"], "correct": "Bill Gates" }, { "question": "1 byte = ?", "choices": ["8 bits", "64 bits", "1024 bits"], "correct": "8 bits" }, { "question": "The C programming language was developed by?", "choices": ["Brendan Eich", "Dennis Ritchie", "Guido van Rossum"], "correct": "Dennis Ritchie" }, { "question": "What does CC mean in emails?", "choices": ["Carbon Copy", "Creative Commons", "other"], "correct": "Carbon Copy" }, { "question": "wsxwsxwsxwsxwsxwsx?", "choices": ["wsx", "edc", "qaz"], "correct": "wsx" }, { "question": "qazqazqazqazqazqaz?", "choices": ["qaz", "wsx", "edc"], "correct": "qaz" }, { "question": "asdasdasdasdasdasd?", "choices": ["asd", "qwe", "zxc"], "correct": "asd" }, { "question": "zxczxczxczxczxczxc?", "choices": ["zxc", "asd", "qwe"], "correct": "zxc" }, { "question": "qweqweqweqweqweqwe?", "choices": ["qwe", "asd", "zxc"], "correct": "qwe" }]; console.log(pickFrom(3, quiz)); 

Necesitas escribir algo de lógica. A continuación se muestra un ejemplo de ejemplo.

  var list = [1, 2, 3, 4, 5]; var listDone = []; var inProcess = true; while(inProcess){ var randomQuiz = Math.floor(Math.random() * list.length); var isDone = false; for (var j = 0; j < listDone.length; j++) { if (listDone[j] === randomQuiz) isDone = true; } if (!isDone) { console.log(list[randomQuiz]);//Display if not Done. listDone.push(randomQuiz); } if (list.length == listDone.length) inProcess = false; } 

Agregué una variable questionCounter que se incrementará cuando se llame a su función de pregunta de pregunta. También modifiqué su statement if if para usar el contador de preguntas para configurar el texto de su botón de envío. Vista previa en vivo: http://codepen.io/larryjoelane/pen/yeKwqO

JavaScript:

 var questionCounter = 0; var quiz = [{ "question": "What is the full form of IP?", "choices": ["Internet Provider", "Internet Port", "Internet Protocol"], "correct": "Internet Protocol" }, { "question": "Who is the founder of Microsoft?", "choices": ["Bill Gates", "Steve Jobs", "Steve Wozniak"], "correct": "Bill Gates" }, { "question": "1 byte = ?", "choices": ["8 bits", "64 bits", "1024 bits"], "correct": "8 bits" }, { "question": "The C programming language was developed by?", "choices": ["Brendan Eich", "Dennis Ritchie", "Guido van Rossum"], "correct": "Dennis Ritchie" }, { "question": "What does CC mean in emails?", "choices": ["Carbon Copy", "Creative Commons", "other"], "correct": "Carbon Copy" }, { "question": "wsxwsxwsxwsxwsxwsx?", "choices": ["wsx", "edc", "qaz"], "correct": "wsx" }, { "question": "qazqazqazqazqazqaz?", "choices": ["qaz", "wsx", "edc"], "correct": "qaz" }, { "question": "asdasdasdasdasdasd?", "choices": ["asd", "qwe", "zxc"], "correct": "asd" }, { "question": "zxczxczxczxczxczxc?", "choices": ["zxc", "asd", "qwe"], "correct": "zxc" }, { "question": "qweqweqweqweqweqwe?", "choices": ["qwe", "asd", "zxc"], "correct": "qwe" }]; var currentQuestion = Math.floor(Math.random() * quiz.length); // define elements var content = $("content"), questionContainer = $("question"), choicesContainer = $("choices"), scoreContainer = $("score"), submitBtn = $("submit"); score = 0, askingQuestion = true; function $(id) { // shortcut for document.getElementById return document.getElementById(id); } function askQuestion() { //increment the counter questionCounter++; var choices = quiz[currentQuestion].choices, choicesHtml = ""; // loop through choices, and create radio buttons for (var i = 0; i < choices.length; i++) { choicesHtml += "" + " 
"; } // load the question questionContainer.textContent = "Q" + (questionCounter) + ". " + quiz[currentQuestion].question; // load the choices choicesContainer.innerHTML = choicesHtml; // setup for the first time if (questionCounter === 1) { scoreContainer.textContent = "Score: 0 right answers out of " + quiz.length + " possible."; submitBtn.textContent = "Submit Answer"; } } function checkAnswer() { // are we asking a question, or proceeding to next question? if (askingQuestion) { submitBtn.textContent = "Next Question"; askingQuestion = false; // determine which radio button they clicked var userpick, correctIndex, radios = document.getElementsByName("quiz" + currentQuestion); for (var i = 0; i < radios.length; i++) { if (radios[i].checked) { // if this radio button is checked userpick = radios[i].value; } // get index of correct answer if (radios[i].value == quiz[currentQuestion].correct) { correctIndex = i; } } // setup if they got it right, or wrong var labelStyle = document.getElementsByTagName("label")[correctIndex].style; labelStyle.fontWeight = "bold"; if (userpick == quiz[currentQuestion].correct) { score++; labelStyle.color = "green"; } else { labelStyle.color = "red"; } scoreContainer.textContent = "Score: " + score + " right answers out of " + quiz.length + " possible."; } else { // move to next question // setting up so user can ask a question askingQuestion = true; // change button text back to "Submit Answer" submitBtn.textContent = "Submit Answer"; // if we're not on last question, increase question number if (currentQuestion < quiz.length - 1) { currentQuestion++; askQuestion(); } else { showFinalResults(); } } } function showFinalResults() { content.innerHTML = "

You've complited the quiz!

" + "

Below are your results:

" + "

" + score + " out of " + quiz.length + " questions, " + Math.round(score / quiz.length * 100) + "%

"; } window.addEventListener("load", askQuestion, false); submitBtn.addEventListener("click", checkAnswer, false);