3

I have some code for storing a random value from an array into a variable like this:

Quest=["value1","value2","value3","value4"];
var random=Math.floor( Math.random() * Quest.length );
var question = Quest[random];

I call the second and third lines of code several times,so the same value gets generated more than once.Does anyone have any idea for some efficient code to ensure that the same value is not repeatedly generated more than once in order?

Ronophobia
  • 349
  • 3
  • 16
  • Do you mean that your random number should not be generated like this 2,1,3,3,3,1,2,... Those subsequent 3's should be once there right...?? – Prasath K Mar 28 '13 at 07:01
  • You got four options and you don't want a number to be repeated (consecutively)? How constrained is your requirement! – asgs Mar 28 '13 at 07:03
  • Yep exactly.But I want it like this preferably-2,1,3,4,... or 1,3,4,2...etc. – Ronophobia Mar 28 '13 at 07:05

4 Answers4

2
  • Populate an array with the numbers 0 through (Quest.length-1).

  • Use this JavaScript code to shuffle that array.

Repeat:

  • For first time(t=0),output array[t].

  • For second time(t=1),output array[t].

  • when t%Quest.length (or array.length)==0.

  • Again shuffle the array.

    and Repeat.

        function shuffle(o) 
        { 
         for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
            return o;
        };
        Quest = ["value1", "value2", "value3", "value4"];
        var myarray = new Array();
        var i = 0;
        for (i = 0; i < Quest.length; i++) {
            myarray[i] = i;
        }
        shuffle(myarray);
        for (i = 0; i < myarray.length; i++) {
            document.write(myarray[i]);
        }
        for (i = 0; i < 50; i++) {
            if (i % (Quest.length) == 0) {
                shuffle(myarray);
            }
            document.write("<p>" + Quest[myarray[i % (Quest.length)]] + "</p>");
        }
    
Ritesh Kumar Gupta
  • 5,055
  • 7
  • 45
  • 71
2

You can do it using splice method:

var Quest = ["value1", "value2", "value3", "value4"];
var random1 = Quest.splice(Math.floor(Math.random() * Quest.length), 1)[0];
...
var random2 = Quest.splice(Math.floor(Math.random() * Quest.length), 1)[0];
... 
var random3 = Quest.splice(Math.floor(Math.random() * Quest.length), 1)[0];

Since the value is removed from the Quest array it's guaranteed that questions will never repeat

Demo: http://jsfiddle.net/dfsq/QUztw/3/

Note: if you don't want to modify the initial array you can work with its copy Quest.slice().

dfsq
  • 191,768
  • 25
  • 236
  • 258
  • Haha how many times did you edit this? This is very useful but could you please elaborate on that Note? – Ronophobia Mar 28 '13 at 07:31
  • 1
    `splice` removes elements from array. If you don't want this behavior you should use array clone: `var questClone = Quest.slice(); var random1 = questClone.splice(...)`. – dfsq Mar 28 '13 at 07:35
2

Use Fisher-Yates to shuffle the array:

var Quest=["value1","value2","value3","value4"];

function kfy(array)
{
  for (var i = array.length - 1; i > 0; --i) {
    var p = Math.floor(Math.random() * (i + 1)),
    tmp = array[p];
    array[p] = array[i];
    array[i] = tmp;
  }
}

console.log(Quest);
kfy(Quest);
console.log(Quest);

Then, just iterate from the beginning to the end of your array.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
1

Another possibility is to random-sort the array:

function randomOrder() {
 return (Math.round(Math.random())-0.5);
}

var Quest = ["value1", "value2", "value3", "value4"];
Quest.sort(randomOrder);

At that point you can walk the array and it shouldn't repeat.

yzxben
  • 862
  • 6
  • 11
  • On bigger arrays this will lead to a biased sort, because each item may be shuffled more than once. – Ja͢ck Mar 28 '13 at 07:43