Javascript not producing a random number
I have a while loop to generate a random number that is not the same as any other random number produced before. The random number is used to select a text value of an object.
for example:
quoteArray[1] = "some text" quoteArray[2] = "some different text" quoteArray[3] = "text again" quoteArray[4] = "completely different text" quoteArray[5] = "ham sandwich"
This is part of a larger function and after this function has cycled = quoteArray.length it resets itself and starts the cycle again. The problem I have is that the following code is SOMETIMES producing an infinite loop:
//Note: at this point in the function I have generated a random number once already and stored it in 'randomnumber' //I use this while statement to evaluate 'randomnumber' until the condition of it NOT being a number that has already been used and NOT being the last number is met. while(randomnumber === rotationArray[randomnumber] || randomnumber === lastnumber){ randomnumber = Math.floor(Math.random() * (quoteArray.length)); }
When I console.log (randomnumber) - when I'm stuck in the loop - I just get '0' accordingly. When it is stuck in the loop, it does not seem that Math.floor (Math.random () * (quoteArray.length)) produces a random number but rather "0" infinitely.
Can anyone tell me why I am facing this problem?
EDIT: Here is the complete complete code with function + variable declarations
// Function to initialize the quoteObj function quoteObj (text, cname, ccompany, url, height) { this.text = text; this.cname = cname; this.ccompany = ccompany; this.url = url; this.height = height; } // Fill my Subject quotes with quote information from the XML sheet. var qObj = new quoteObj ('', '', '', '')); var quoteArray = new Array (); var counter = 0; // review each XML element and load the data into an object that is then stored in an array $ .ajax ({ type: "GET", url: "quotes.xml", dataType: "xml", success: function (xml) { $ (xml) .find ('quote'). each (function () { quoteArray [counter] = new quoteObj ('', '', '', '')); console.log (quoteArray [counter]); quoteArray [counter] .text = $ (this) .find ('text'). text (); quoteArray [counter] .cname = $ (this) .find ('customer_name'). text (); quoteArray [counter] .ccompany = $ (this) .find ('customer_company'). text (); quoteArray [counter] .url = $ (this) .find ('project'). text (); ++ counter; }); } }); // This is the setion that generates my infinite loop problem. // I included all the other code in case people would ask specific questions about how an item was initialized, etc. // Generate a random first citation then progress randomly through the whole set and start all over again. var randomnumber = Math.floor (Math.random () * (quoteArray.length)); var rotationArray = new array (quoteArray.length); var v = 0; var lastnumber = -1; bHeight = $ ('# rightbox'). height () + 50; var cHeight = 0; var divtoanim = $ ('# customerquotes'). parent (); //NO LINK// // Give a height to the inner shadow for the hidden overflow to work with the quotes. $ (divtoanim) .css ({'height': bHeight}); // Rotate the Random Quotations function. setInterval (function () { randomnumber = Math.floor (Math.random () * (quoteArray.length)); // check if the function loop should start at the beginning. if (v == (quoteArray.length)) { rotationArray.length = 0; v = 0; } // determine if the random number is at the same time different from any other random number generated before and it is not the same as the last random number while (randomnumber === rotationArray [randomnumber] || random_number === lastnumber) { randomnumber = Math.floor (Math.random () * (quoteArray.length)); } lastnumber = random number; rotationArray [randomnumber] = random number; ++ v; //NO LINK// // animation sequence $ ('# ctext, #cname'). animate ({'opacity': '0'}, 2000, function () { $ ('# ctext'). html (quoteArray [random number] .text); $ ('# cname'). html ('-' + quoteArray [random number] .cname); cHeight = $ ('# customerquotes'). height () + 50; adjustHeight (bHeight, cHeight, divtoanim); $ ('# ctext'). delay (500) .animate ({'opacity': '1'}, 500); $ ('# cname'). delay (1500) .animate ({'opacity': '1'}, 500); }); }, 15000);
The answer
First of all, since you have updated your question, make sure that you manage the asynchronous data correctly. Because an ajax call is asynchronous, you must make sure that you start the randomizer only after the call is successful and the data returned.
Secondly, assuming you handle the data asyc correctly, the size of your result set is probably too small. So, you probably get the same number at random. Then you can not use this number because you have already done so.
What you need to do is to remove the parts that are already used from the scoreboard each time. Recalculate the length of the array, then draw a random one. However, the probability of this random feeling is very slim.
There is probably a more efficient way to do this, but here is my go:
var results = ['some text','some text2','some text3','some text4','some text5', /* ...etc */ ], randomable = results; function getRandomOffset( arr ) { var offset, len; if( arr.length < 1 ) return false; else if( arr.length > 1 ) offset = Math.floor(Math.random() * arr.length ); else offset = 0; arr.splice( offset, 1 ); return [ offset, arr ]; } while( res = getRandomOffset( randomable ) ) { // Set the randomable for next time randomable = res[1]; // Do something with your resulting index results[ res[0] ]; }
Read More Articles
0 Comments:
Posting Komentar