1

I have an array of questions that I want to randomize and put into a quiz. However currently it can choose the same question twice and put it in the quiz twice. If I want to delete the question after it has been pushed to a new array, without knowing its index how can I remove it?

My code that i tried was this

var index = questionsArrayCopy.findIndex(function(item, i){return item.question === randomQuestion});
questionsArrayCopy.splice(index)

But it didn't work and I had no errors

My current code is below:

const myQuestions = [
  {
    question: 'What is 37 x 89?',
    answers: [
      { text: '6989', correct: false },
      { text: '3293', correct: true },
      { text: '2400', correct: false },
      { text: '9870', correct: false }
    ]
  },
  {
    question: 'What year is the great fire of london?',
    answers: [
      { text: '1666', correct: true },
      { text: '1888', correct: false },
      { text: '1600', correct: false },
      { text: '1566', correct: false }
    ]
  },
  {
    question: 'Is web development fun?',
    answers: [
      { text: 'Kinda', correct: false },
      { text: 'YES!!!', correct: true },
      { text: 'Um no', correct: false },
      { text: 'IDK', correct: false }
    ]
  },
  {
    question: 'What is 4 * 2?',
    answers: [
      { text: '6', correct: false },
      { text: '8', correct: true }
    ]
  },
]

function getRandomNumberBetween(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

const GetRandomQuestionFromArray = (array) => {
   const randomIndex = getRandomNumberBetween(0, array.length);
   return array[randomIndex];
}

const GetRandomQuestionsArray = (howManyQuestions) => {
  const questionsArrayCopy = [...myQuestions];
  const finalQuestionArray = [];

  for (let i = 0; i < howManyQuestions; i++) {
      const randomQuestion = GetRandomQuestionFromArray(questionsArrayCopy);
      finalQuestionArray.push(randomQuestion);
  }
  return finalQuestionArray;
}

const questions = GetRandomQuestionsArray(3);
console.log(questions)

If I want to stop duplicate questions from entering the final array(questions) and just choose random ones from the other array(myQuestions) how would I do that?

Yevhen Horbunkov
  • 14,965
  • 3
  • 20
  • 42
Pepe
  • 41
  • 7
  • 2
    Instead of picking a random question why not just shuffle the question array randomly and take `n` entries? It solves half the problems you have and leave you with just one - how to randomly shuffle an array and that is [easy to find](https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array). – Jamiec Oct 25 '20 at 09:34
  • `splice(index, 1)` = how many to remove (1). [Array.prototype.splice()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) – iAmOren Oct 25 '20 at 09:35
  • What you're trying to achieve is known as [Fisher-Yates](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) method for shuffling. You may check out one of the possible implementations of it [over here](https://stackoverflow.com/a/56756447/11299053) – Yevhen Horbunkov Oct 25 '20 at 09:41
  • I agree with @Jamiec. but iAmOren is right about the problem with the code :-) – Thatkookooguy Oct 25 '20 at 09:42

4 Answers4

2

You already had the index of the item you picked, you just threw it away:

const GetRandomQuestionFromArray = (array) => {
   const randomIndex = getRandomNumberBetween(0, array.length); //<-- here it is!!
   return array[randomIndex];
}

So seeing as that method really doesn't help you much just move the logic to the method calling it, and then use splice to remove that index:

const GetRandomQuestionsArray = (howManyQuestions) => {
  const questionsArrayCopy = [...myQuestions];
  const finalQuestionArray = [];

  for (let i = 0; i < howManyQuestions; i++) {
      const randomIndex = getRandomNumberBetween(0, questionsArrayCopy .length);
    
      const randomQuestion = questionsArrayCopy.splice(randomIndex,1);
      finalQuestionArray.push(randomQuestion[0]);
  }
  return finalQuestionArray;
}

Live example:

const myQuestions = [
  {
    question: 'What is 37 x 89?',
    answers: [
      { text: '6989', correct: false },
      { text: '3293', correct: true },
      { text: '2400', correct: false },
      { text: '9870', correct: false }
    ]
  },
  {
    question: 'What year is the great fire of london?',
    answers: [
      { text: '1666', correct: true },
      { text: '1888', correct: false },
      { text: '1600', correct: false },
      { text: '1566', correct: false }
    ]
  },
  {
    question: 'Is web development fun?',
    answers: [
      { text: 'Kinda', correct: false },
      { text: 'YES!!!', correct: true },
      { text: 'Um no', correct: false },
      { text: 'IDK', correct: false }
    ]
  },
  {
    question: 'What is 4 * 2?',
    answers: [
      { text: '6', correct: false },
      { text: '8', correct: true }
    ]
  },
]

function getRandomNumberBetween(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

const GetRandomQuestionsArray = (howManyQuestions) => {
  const questionsArrayCopy = [...myQuestions];
  const finalQuestionArray = [];

  for (let i = 0; i < howManyQuestions; i++) {
      const randomIndex = getRandomNumberBetween(0, questionsArrayCopy.length);

      const randomQuestion = questionsArrayCopy.splice(randomIndex,1);
      finalQuestionArray.push(randomQuestion[0]);
  }
  return finalQuestionArray;
}
const questions = GetRandomQuestionsArray(3);
console.log(questions)

However as I said in my comment, an easier solution is often to just shuffle the initial array randomly, and then take however many items you want from it:

function shuffle(array) {
  var currentIndex = array.length, temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}
var questions = ["question1","question2","question3","question4","question5"];

var shuffled = shuffle(questions);

console.log(shuffled[0],shuffled[1],shuffled[2]);
Jamiec
  • 133,658
  • 13
  • 134
  • 193
1

Use the filter method in an array

const result = myQuestions.filter(el => el.question !=='What is 4 * 2?');

console.log(result)
Yoel
  • 7,555
  • 6
  • 27
  • 59
1

Use a while loop and inside, only add the question to your final array if it's not already present.

Use the find method to check if the question already exists.

There is no need to duplicate your array

const myQuestions = [
  {
    question: 'What is 37 x 89?',
    answers: [
      { text: '6989', correct: false },
      { text: '3293', correct: true },
      { text: '2400', correct: false },
      { text: '9870', correct: false }
    ]
  },
  {
    question: 'What year is the great fire of london?',
    answers: [
      { text: '1666', correct: true },
      { text: '1888', correct: false },
      { text: '1600', correct: false },
      { text: '1566', correct: false }
    ]
  },
  {
    question: 'Is web development fun?',
    answers: [
      { text: 'Kinda', correct: false },
      { text: 'YES!!!', correct: true },
      { text: 'Um no', correct: false },
      { text: 'IDK', correct: false }
    ]
  },
  {
    question: 'What is 4 * 2?',
    answers: [
      { text: '6', correct: false },
      { text: '8', correct: true }
    ]
  },
]

function getRandomNumberBetween(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

const getRandomQuestionFromArray = (array) => {
   const randomIndex = getRandomNumberBetween(0, array.length - 1);
   return array[randomIndex];
}

const getRandomQuestionsArray = (howManyQuestions) => {
  const finalQuestionArray = [];

  // Continue until number of questions requested is reached
  while (finalQuestionArray.length < howManyQuestions) {
      const randomQuestion = getRandomQuestionFromArray(myQuestions);
      
      // check if the random question is already present in the final result
      if (!finalQuestionArray.find(q => q.question === randomQuestion.question)) {
        finalQuestionArray.push(randomQuestion);
      }
  }
  return finalQuestionArray;
}

const questions = getRandomQuestionsArray(3);
console.log(questions);
klugjo
  • 19,422
  • 8
  • 57
  • 75
  • Thankyou, how could I get multiple questions EG. get 3 different questions randomly chosen from myQuestions whilst keeping the question and answer data – Pepe Oct 25 '20 at 09:48
  • @Pepe my example shows you exactly that. It gets 3 unique random questions from `myQuestions` – klugjo Oct 25 '20 at 09:50
  • This is about the _worst_ solution to this problem you could use. 1) It's hugely inefficient, possibly looping for ever 2) You already had the index of the item you picked, you just threw it away. 3) It's much easier to solve by randomizing the array first and taking however many items you want. – Jamiec Oct 25 '20 at 14:24
-2

use filter mentod in array java script

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

const myQuestions = [
  {
    question: 'What is 37 x 89?',
    answers: [
      { text: '6989', correct: false },
      { text: '3293', correct: true },
      { text: '2400', correct: false },
      { text: '9870', correct: false }
    ]
  },
  {
    question: 'What year is the great fire of london?',
    answers: [
      { text: '1666', correct: true },
      { text: '1888', correct: false },
      { text: '1600', correct: false },
      { text: '1566', correct: false }
    ]
  },
  {
    question: 'Is web development fun?',
    answers: [
      { text: 'Kinda', correct: false },
      { text: 'YES!!!', correct: true },
      { text: 'Um no', correct: false },
      { text: 'IDK', correct: false }
    ]
  },
  {
    question: 'What is 4 * 2?',
    answers: [
      { text: '6', correct: false },
      { text: '8', correct: true }
    ]
  },
]

const result = myQuestions.filter(el => el.question !=='What is 4 * 2?');

console.log(result)
Yoel
  • 7,555
  • 6
  • 27
  • 59