0

I want to randomize the order of the choices. I added a script that was supposed to shuffle the order of the choices but it failed to do so. Nothing displays when I debug the quiz.

Here's the code that I added:

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;
}

Javascript Quiz:

 var quiz = [{
          "question": "What is the full form of IP?",
          "choices": ["Internet Provider", "Internet Port", "Internet Protocol" , "Other"],
          "correct": "Other"

        }, {
          "question": "Who is the founder of Microsoft?",
          "choices": ["Bill Gates", "Steve Jobs", "Steve Wozniak" , "Martin Shaba"],
          "correct": "Bill Gates"
        }, {
          "question": "What was your first dream?",
          "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"
        }];
1

2 Answers 2

1

Add a scramble function to Array.prototype:

if (!("scramble" in Array.prototype)) {
  Object.defineProperty(Array.prototype, "scramble", {
    enumerable: false,
    value: function() {
      var o, i, ln = this.length;
      while (ln--) {
        i = Math.random() * (ln + 1) | 0;
        o = this[ln];
        this[ln] = this[i];
        this[i] = o;
      }
      return this;
    }
  });
}
var quiz = [{
  "question": "What is the full form of IP?",
  "choices": ["Internet Provider", "Internet Port", "Internet Protocol", "Other"],
  "correct": "Other"
}];

quiz.forEach(q => q.choices.scramble());

console.log(quiz[0].choices);


Originally I had suggested:

quiz.forEach(q => q.choices.sort(() => Math.random() - .5));

DanDavis pointed out that particular method didn't achieve a reasonable distribution.

Sign up to request clarification or add additional context in comments.

7 Comments

Perfect! Thank you so much! @canon
Such a simple and amazing answer and its a one liner so that's a bonus, well done canon.
not random: the more answers on a question, the less random later choices will be. it's a very common mis-conception that this random-sort actually randomizes an array instead of just muddling up the head a bit...
consider this code: fiddle.jshell.net/czdnwdoh ... 20-30 is ok, but i rarely saw anything under 40... if i had a die tha came up 3 half the time, i would be rich or dead...
@canon: that looks 100% better. ok, well it looks worse, but it works perfectly.
|
1

If you wanted "Other" to remain as the last choice after the shuffle, you could accomplish that with this code:

var quiz = [{
  "question": "What is the full form of IP?",
  "choices": ["Internet Provider", "Internet Port", "Internet Protocol", "Other"],
  "correct": "Other"
}, {
  "question": "Who is the founder of Microsoft?",
  "choices": ["Bill Gates", "Steve Jobs", "Steve Wozniak", "Martin Shaba"],
  "correct": "Bill Gates"
}, {
  "question": "What was your first dream?",
  "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"
}];

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

    // While there remain elements to shuffle...
    while (currentIndex > 1) {

        // 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;
}

quiz.forEach(function(question) {
    var otherIndex;
    var choices = question.choices;
    var lastIndex = choices.length - 1;
    shuffle(choices);
    otherIndex = choices.indexOf('Other');
    if (otherIndex >= 0) {
        choices[otherIndex] = choices[lastIndex];
        choices[lastIndex] = 'Other';
    }
    console.log(choices);
});

1 Comment

yeah, that doesn't randomize the array either... and why not just save and push() the last one instead of searching for it and mutating the array in the middle?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.