0

I'm trying to modify this quiz app from a tutorial from Awais Mirza

I would like to pick a random selection of questions from a master array and push it in to a selection array the script uses to populate questions, so the quiz will give a random set of questions form the master array every time the quiz is run. I thought i could use Fisher-Yates shuffle to randomize the master array before pushing the selected number of questions into a selection array.

Why does the Fisher-Yates shuffle work with this array;

var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];

var i = arr.length, j, temp;
while(--i > 0){
    j = Math.floor(Math.random()*(i+1));
    temp = arr[j];
    arr[j] = arr[i];
    arr[i] = temp;
}
console.log(arr);

but not with this array?

var Questions = [
    new Question("What comes after 1?", ["1", "2","3", "4"], "2"),
    new Question("What comes after 2?", ["1", "2", "3", "4"], "3"),
    new Question("What comes after 3?", ["1", "2", "3", "4"], "4")
];
Dinshaw Raje
  • 933
  • 1
  • 12
  • 33
  • 2
    Welcome to Stack Overflow! Please take the [tour] (you get a badge!), have a look around, and read through the [help], in particular [*How do I ask a good question?*](/help/how-to-ask) I also recommend Jon Skeet's [Writing the Perfect Question](https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/) and [Question Checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). Please [**search**](/search?q=%5Bjs%5D+fisher+yates) before posting. More about searching [here](/help/searching). – T.J. Crowder Jan 19 '20 at 13:08
  • 1
    This seems to have been closed as a dup a bit to fast. Sure, the [duplicate](https://stackoverflow.com/q/6274339/4003419) has the code for the modern Fisher-Yates shuffle. But this question is about why it doesn't work on his array of objects. – LukStorms Jan 19 '20 at 14:07
  • 3
    I see no reason why it shouldn't work the same way. Can you create a runnable snippet that exhibits the issue? You haven't really shared the affected code so there's no way to tell what you're doing wrong. – Álvaro González Jan 20 '20 at 09:38
  • It works in a clean env: https://repl.it/repls/DimgrayCourageousListeners (hit "Run" a few times). I think there's something more you need to provide us with. – Sebastian Kaczmarek Jan 20 '20 at 10:19

3 Answers3

2

The Fisher-Yates algorithm works exclusively with array indexes so you don't need different implementations depending on array contents.

To illustrate that I've moved the sorting code to a function so it can be reused:

function shuffle(arr) {
  var i = arr.length, j, temp;
  while(--i > 0){
    j = Math.floor(Math.random()*(i+1));
    temp = arr[j];
    arr[j] = arr[i];
    arr[i] = temp;
  }
}

class Question {
  constructor(title, options, solution) {
    this.title = title;
    this.options = options;
    this.solution = solution;
  }
}

var integerArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
var questions = [
    new Question("What comes after 1?", ["1", "2","3", "4"], "2"),
    new Question("What comes after 2?", ["1", "2", "3", "4"], "3"),
    new Question("What comes after 3?", ["1", "2", "3", "4"], "4")
];
shuffle(integerArray);
shuffle(questions);
console.log(integerArray, questions);
Álvaro González
  • 142,137
  • 41
  • 261
  • 360
0

Could be a tad easier with randojs.com, which uses this method of shuffling, but it's completely preference.

function Question(question, choices, answer){ this.question = question; this.choices = choices; this.answer = answer; }

// create questions
var questions = [
    new Question("Which one is not an object oriented programming language?", ["Java", "C#","C++", "C"], "C"),
    new Question("Which language is used for styling web pages?", ["HTML", "JQuery", "CSS", "XML"], "CSS"),
    new Question("There are ____ main components of object oriented programming.", ["1", "6","2", "4"], "4"),
    new Question("Which language is used for web apps?", ["PHP", "Python", "Javascript", "All"], "All"),
    new Question("MVC is a ____.", ["Language", "Library", "Framework", "All"], "Framework")
];

// Shuffle array
var sequence = randoSequence(questions);
sequence.forEach((item, i) => {sequence[i] = item.value;});

// choose 3 first questions from shuffeled array
var selection = sequence.slice(0, 3);

console.log(selection);
<script src="https://randojs.com/1.0.0.js"></script>
Aaron Plocharczyk
  • 2,776
  • 2
  • 7
  • 15
-1

I solved it with this:

// create questions
var questions = [
    new Question("Which one is not an object oriented programming language?", ["Java", "C#","C++", "C"], "C"),
    new Question("Which language is used for styling web pages?", ["HTML", "JQuery", "CSS", "XML"], "CSS"),
    new Question("There are ____ main components of object oriented programming.", ["1", "6","2", "4"], "4"),
    new Question("Which language is used for web apps?", ["PHP", "Python", "Javascript", "All"], "All"),
    new Question("MVC is a ____.", ["Language", "Library", "Framework", "All"], "Framework")
];

// Shuffle array
var arr = questions;
var i = arr.length, j, temp;
while(--i > 0){
    j = Math.floor(Math.random()*(i+1));
    temp = arr[j];
    arr[j] = arr[i];
    arr[i] = temp;
}

// choose 3 first questions from shuffeled array
var selection = arr.slice(0, 3);

// create quiz
var quiz = new Quiz(selection);

// display quiz
populate();
Rohit Gupta
  • 4,022
  • 20
  • 31
  • 41