简体   繁体   中英

How can I select a random object from an array and then remove it so it doesn't get repeated?

I'm beginner Javascript student and have to make a trivia game. I have an array of objects which are questions. I want to randomly select an object(question) and then use it, and then get rid of it so that it doesn't get brought up again when I pick the next question. How can I do this correctly? What I have tried so far is:

class Question
{
constructor(t,oA,oB,oC,oD,ans)
{
  this.title=t;
  this.optionA=oA;
  this.optionB=oB;
  this.optionC=oC;
  this.optionD=oD
  this.answer=ans;
}

  displayQuestion1R1()
 {
      userAnswer=prompt(`${this.title}\nA.${this.optionA}\nB.${this.optionB}\nC.${this.optionC}\nD.${this.optionD}`);
 }

}

Round1Questions.push(new Question("According to scientists, how old, 
approximately, is Earth?", "3 billions years", "100 million years", "4.5 
billion years","2.5 billion years", "4.5 billion years"));

Round1Questions.push(new Question("Who was the first American President?", 
"Benjamin Franklin", "Barack Obama", "George Washington","Thomas Jefferson", 
"George Washington"));

Round1Questions.push(new Question("How many Presidents have there been up to 
this year?(2019)?", "45", "40", "60","46", "45"));

Round1Questions.push(new Question("What is the largest Ocean in the world?", 
"Atlantic Ocean", "Pacific Ocean", "Indian Ocean","Arctic Ocean", "Pacific 
Ocean"));

Round1Questions.push(new Question("Which one of the following is not a 
Marvel super-hero?","Spider-Man","Hulk","Batman", "Iron Man", "Batman"));

let ri=RoundQuestions1[Math.floor(Math.random()*Round1Questions.length)];
let question1R1=Round1Questions.splice(ri, 1);

question1R1.displayQuestion1R1();

When I try to run this it says question1R1.displayQuestion1R1() is not a function. However if I remove the splice method I have and just do let question1R1=RoundQuestions1[Math.floor(Math.random()*Round1Questions.length)]; and then do question1R1.displayQuestion1R1() then it works. However that doesn't allow me to remove the question from the array. How can I accomplish this?

Ok Jack Bashford was close too, but splice method return a array value.

 class Question { constructor(t, oA, oB, oC, oD, ans) { this.title = t; this.optionA = oA; this.optionB = oB; this.optionC = oC; this.optionD = oD this.answer = ans; } displayQuestion1R1() { // userAnswer = prompt(`${this.title}\\nA.${this.optionA}\\nB.${this.optionB}\\nC.${this.optionC}\\nD.${this.optionD}`); console.log( `${this.title}\\nA.${this.optionA}\\nB.${this.optionB}\\nC.${this.optionC}\\nD.${this.optionD}` ) } } var Round1Questions = []; Round1Questions.push(new Question("According to scientists, how old, approximately, is Earth ? ", "3 billions years ", "100 million years ", "4.5 billion years ","2.5 billion years ", "4.5 billion years ") ); Round1Questions.push(new Question("Who was the first American President?", "Benjamin Franklin", "Barack Obama", "George Washington", "Thomas Jefferson", "George Washington") ); Round1Questions.push(new Question("How many Presidents have there been up to this year ? (2019) ? ", "45", "40", "60","46", "45") ); Round1Questions.push(new Question("What is the largest Ocean in the world?", "Atlantic Ocean", "Pacific Ocean", "Indian Ocean", "Arctic Ocean", "Pacific Ocean ") ); Round1Questions.push(new Question("Which one of the following is not a Marvel super - hero ? ", " Spider-Man", "Hulk", "Batman", "Iron Man", "Batman ") ); do { let PickQuestion_N = Math.floor(Math.random() * Round1Questions.length), PickedQuestion = Round1Questions.splice(PickQuestion_N, 1)[0] ; PickedQuestion.displayQuestion1R1(); } while (Round1Questions.length > 0) 

Problem

Your approach does not work because of two reasons:

  1. You used RoundQuestions1[Math.floor(Math.random()*Round1Questions.length)] to get your Question instance to assign to r1 variable. Then, you use that instance in Round1Questions.splice(ri, 1) , which is not the expected argument type of Array.prototype.splice method .

  2. Round1Questions.splice(ri, 1) returns an Array. So your question1R1 is an array instead of a Question.

Solution

  1. Instead of getting a random Question, try getting a random Quesiton index instead.
  2. Use the random index to splice the Question bank.
  3. Get the first item of the array returned from .splice . See why here .

Working code below (see comments for explanation):

 class Question { constructor(t, oA, oB, oC, oD, ans){ this.title = t; this.optionA = oA; this.optionB = oB; this.optionC = oC; this.optionD = oD this.answer = ans; } displayQuestion1R1(){ const { title, optionA, optionB, optionC, optionD } = this; const userAnswer = prompt(` ${title} A. ${optionA} B. ${optionB} C. ${optionC} D. ${optionD} `); } } const Round1Questions = [ new Question( "According to scientists, how old, approximately, is Earth?", "3 billions years", "100 million years", "4.5 billion years", "2.5 billion years", "4.5 billion years" ), new Question( "Who was the first American President?", "Benjamin Franklin", "George Washington", "Thomas Jefferson", "George Washington" ), new Question( "How many Presidents have there been up to this year (2019)?", "45", "40", "60", "46", "45" ), new Question( "What is the largest Ocean in the world?", "Atlantic Ocean", "Pacific Ocean", "Indian Ocean", "Arctic Ocean", "Pacific Ocean" ), new Question( "Which one of the following is not a Marvel super-hero?", "Spider-Man", "Hulk", "Batman", "Iron Man", "Batman" ) ]; console.log(`Bank before prompt:`, Round1Questions.map(o => o.title)); // Instead of getting the question, get the index of question let ri = randomQuestionIndex(Round1Questions); // Use `ri` index to splice your question array. // Notice the `[0]` to get the first item in the returned array let question1R1 = Round1Questions.splice(ri, 1)[0]; // No error now because `question1R1` is a `Question` class instance question1R1.displayQuestion1R1(); console.log(`Bank after prompt:`, Round1Questions.map(o => o.title)); function randomQuestionIndex(bank){ return Math.floor(Math.random() * bank.length); } 
 /* NOT RELATED TO YOUR CODE */ /* JUST TO MAKE CONSOLE MORE VISIBLE */ .as-console-wrapper { max-height: 100% !important; } 

PS

Don't copy paste any answer here because your professor will immediately find out.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM