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"
        }];
Martin
  • 101
  • 2
  • 11
  • 1
    Possible duplicate of [How to randomize (shuffle) a JavaScript array?](http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array) – Dexygen Mar 26 '16 at 06:20

2 Answers2

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.

Jed Fox
  • 2,979
  • 5
  • 28
  • 38
canon
  • 40,609
  • 10
  • 73
  • 97
  • Thanks for your answer! This works but it's randomizing the questions not the choices @canon – Martin Mar 26 '16 at 02:15
  • 1
    Perfect! Thank you so much! @canon – Martin Mar 26 '16 at 02:18
  • 2
    Such a simple and amazing answer and its a one liner so that's a bonus, well done canon. –  Mar 26 '16 at 02:29
  • @dandavis it's working like I want it to, I don't get your point – Martin Mar 26 '16 at 02:57
  • 1
    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... – dandavis Mar 26 '16 at 03:06
  • 1
    consider this code: https://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... – dandavis Mar 26 '16 at 03:29
  • 1
    @canon: that looks 100% better. ok, well it _looks_ worse, but it _works_ perfectly. – dandavis Mar 26 '16 at 06:17
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);
});
Gary S.
  • 146
  • 5
  • 1
    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? – dandavis Mar 26 '16 at 03:37