Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 11 of 11
  1. #1
    New Coder
    Join Date
    Jun 2012
    Posts
    26
    Thanks
    25
    Thanked 0 Times in 0 Posts

    How to stop randomizing Array repeats

    Hi

    Just wondering when randomizing values in an array how I can prevent the same value being randomly generated twice in a row (ie value stays the same). In my vocab flashcards script when clicking 'next word' it sometimes just returns the same word. Note: I'm not looking to randomize the array and then step through it incrementally. It's ok if the word pops up again soon in the stack.

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Japanese Flashcards</title>
    </head>
    
    <body>
    
    <h1>Japanese Flashcards</h1>
    <p id="japanese"></p>
    <p id="english">&nbsp;</p>
    
    <button onclick="showEnglish()">Answer</button>
    <button onclick="nextWord()">Next word</button>
    
    <script type="text/javascript">
    var words = 
    [
        ["taberu",  "to eat"], 
        ["yomu",    "to read"], 
        ["iku",     "to go"], 
    	["kaku",     "to write"],
    	["yomu",    "to drink"],
    	
    ];
    var  cnt = Math.floor((Math.random()*5)+0); 
    document.getElementById("japanese").innerHTML=words[cnt][0];
    
    function showEnglish()
    {    
    	document.getElementById("english").innerHTML = words[cnt][1];    
    }	
    
    function nextWord()
    {
        cnt = Math.floor((Math.random()*5)+0); 
    	
    
        document.getElementById("japanese").innerHTML = words[cnt][0] 
        document.getElementById("english").innerHTML='&nbsp;';
    }
    
    
    </script>
    </body>
    </html>

  • #2
    Senior Coder
    Join Date
    Mar 2005
    Location
    Portsmouth UK
    Posts
    4,536
    Thanks
    3
    Thanked 513 Times in 500 Posts
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Japanese Flashcards</title>
    </head>
    
    <body>
    
    <h1>Japanese Flashcards</h1>
    <p id="japanese"></p>
    <p id="english">&nbsp;</p>
    
    <button onclick="showEnglish()">Answer</button>
    <button onclick="nextWord()">Next word</button>
    
    <script type="text/javascript">
    var words =
    [
        ["taberu",  "to eat"],
        ["yomu",    "to read"],
        ["iku",     "to go"],
    	["kaku",     "to write"],
    	["yomu1",    "to drink"],
    
    ];
    var  cnt = Math.floor((Math.random()*5)+0);
    document.getElementById("japanese").innerHTML=words[cnt][0];
    
    function showEnglish()
    {
    	document.getElementById("english").innerHTML = words[cnt][1];
    }
    
    function nextWord()
    {
        var ncnt = Math.floor((Math.random()*5)+0);
        while (ncnt==cnt){
         ncnt = Math.floor((Math.random()*5)+0);
        }
        cnt=ncnt;
        document.getElementById("japanese").innerHTML = words[cnt][0]
        document.getElementById("english").innerHTML='&nbsp;';
    }
    
    
    </script>
    </body>
    </html>
    Vic

    God Loves You and will never love you less.

    http://www.vicsjavascripts.org/Home.htm

    If my post has been useful please donate to http://www.operationsmile.org.uk/

  • Users who have thanked vwphillips for this post:

    meridian (06-30-2012)

  • #3
    New Coder
    Join Date
    Jun 2012
    Posts
    26
    Thanks
    25
    Thanked 0 Times in 0 Posts
    Thanks vwphillips. That makes sense but interestingly when I tested it it still occasionally returns the same word (the word stays the same). I'm not sure why. Also, it doesn't seem to be particularly random, but perhaps it is just because it is a small data set.

  • #4
    Regular Coder
    Join Date
    May 2012
    Location
    France
    Posts
    224
    Thanks
    0
    Thanked 32 Times in 30 Posts
    An other method could consist to sort randomly the array (with a myArray.sort(function(a,b){return 0.5-Math.random();})) to take the n first elements...

    But with many elements, all this methods can become very long ! A variant consists to choose progressively the elements among the remaining elements. Here is an example...

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="fr">
    <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta http-equiv="cache-control" content="no-cache">
    <meta name="generator" content="PSPad editor, www.pspad.com">
    <title>Random Values</title>
    <style type="text/css">
    body {margin:0;padding:0;font-family:Georgia;text-align:center;}
    #pge {display:block;width:500px;margin:3px auto;}
    p.snd {cursor:pointer;color:#909;}
    </style>
    </head>
    <body>
    	<div id="pge">
    	<p>A simple method to choosec 50 item among 500<br> 
    	(without sorting the whole collection)</p>
    	<p id="rsp"></p>
    	<p>Click on the page for a new generation</p>
    </div>
    <script type="text/javascript">
    function choose(){
    // With for example 500 items (from 01 to 500) 
    	var nbrItm=500,nbrTrt=0,nbrAtr=50;// Total number of item, number of pulled items and number to be pulled
    	var itmLst='',itmObj={} // array and object with pulled items 
    	do {var k=1+Math.floor(Math.random()*(nbrItm-nbrTrt));// choose of a rank among the remaining items
    		// Reduce k for every remainig item to take the kth, when k is null
    		for (var i=1;;i++) if (typeof(itmObj[i])!='number' && (--k)==0){
    			itmObj[i]=1;itmLst+=','+i;break;}
    		nbrTrt++} 
    	while (nbrTrt!=nbrAtr);
    	itmLst=itmLst.substr(1).split(/,/g).sort(function(a,b){return a-b;}).join(', ');
    	document.getElementById('rsp').innerHTML=itmLst;
    }
    choose();
    window.onclick=choose;	
    </script>
    </body>
    </html>
    This code sort the choosing items
    Last edited by 007julien; 06-30-2012 at 02:22 AM.

  • Users who have thanked 007julien for this post:

    meridian (06-30-2012)

  • #5
    Master Coder felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    6,642
    Thanks
    0
    Thanked 649 Times in 639 Posts
    Quote Originally Posted by 007julien View Post
    An other method could consist to sort randomly the array (with a myArray.sort(function(a,b){return 0.5-Math.random();})) to take the n first elements...
    Using 0.75 instead of 0.5 in that calculation will produce results closer to being random. Anything less than 0.75 is biased toward the original order.
    Stephen
    Learn Modern JavaScript - http://javascriptexample.net/
    Helping others to solve their computer problem at http://www.felgall.com/

    Don't forget to start your JavaScript code with "use strict"; which makes it easier to find errors in your code.

  • Users who have thanked felgall for this post:

    meridian (06-30-2012)

  • #6
    New Coder
    Join Date
    Jun 2012
    Posts
    26
    Thanks
    25
    Thanked 0 Times in 0 Posts
    007julien - I think that is an interesting solution. I will need to study your code though to get my head around it more.

    felgall - That would solve my apparent lack of randomness. I guess the myArray.sort function is more suited to a randomized incremental array though.

    Thanks for that guys.

  • #7
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    18,318
    Thanks
    203
    Thanked 2,566 Times in 2,544 Posts
    If all you want to do is prevent the same word appearing twice in succession then you could use:-

    Code:
    var cnt = 0;
    var previous = 0;
    while(cnt == previous) {
    cnt = Math.floor(Math.random()*5);
    }
    previous = cnt;
    alert (cnt);  // for testing
    In other words, if the generated random number is the same as the previous one, generate another one.
    Not strictly random then, but good enough for the purpose. Obviously the larger the number of words the less likely a repeat anyway.

    You could extend this so that the same word was not repeated in any series of three:-

    Code:
    var cnt = 0;
    var previous = 0;
    var beforethat = 0;
    
    while ((cnt == previous) || (cnt == beforethat)) {
    cnt = Math.floor(Math.random()*5);
    }
    beforethat = previous;
    previous = cnt;
    alert (cnt);  // for testing
    Last edited by Philip M; 06-30-2012 at 09:53 AM.

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  • Users who have thanked Philip M for this post:

    meridian (06-30-2012)

  • #8
    New Coder
    Join Date
    Jun 2012
    Posts
    26
    Thanks
    25
    Thanked 0 Times in 0 Posts
    Philip M - that works perfectly. Just what I was trying to do.

    Thanks heaps

  • #9
    Regular Coder
    Join Date
    May 2012
    Location
    France
    Posts
    224
    Thanks
    0
    Thanked 32 Times in 30 Posts
    Take care. The proposed method to sort an array with a function which compare randomly two values is not right (with 0.5 and even more with 0.75) ! The values are generally not uniformly distributed in the interval [0,1) !
    Code:
    // The results of this method depends on the browser
    mydArray.sort(function(a,b){return Math.random()-0.5)})
    The following script shows the distribution obtained with the three methods (the values are grouped by 4 to smooth the distributions)
    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="fr">
    <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta http-equiv="cache-control" content="no-cache">
    <meta name="generator" content="PSPad editor, www.pspad.com">
    <title>Random Values</title>
    <style type="text/css">
    body {margin:0;padding:0;font-family:Georgia;text-align:center;}
    #pge {display:block;width:900px;margin:3px auto;text-align:left;font-size:9px;}
    p{font-size:12px;font-weight:bold;}
    .grp {font-family:"courier new";color:#fff;font-weight:500;}
    .ble {padding:0px;background-color:#039;font-size:6px;}
    </style>
    </head>
    <body>
    	<div id="pge">
    	
    	</div>
    <script type="text/javascript">
    var cards=[];for (var i=0;i<52;i++) cards[i]=i;
    function affiche(o){var i,j,k,g='',s=0,t;
        for (i=0;i<13;i++){j=o[i];s+=j;
    	 	g+=(i<10?'&nbsp;':'')+i+' <span class="ble" style="padding-left:'+((k=Math.ceil(j/3))<800?k:800)+'px" height="5px">'+j+'</span><br>';
    	 }	
    	document.getElementById('pge').innerHTML+='<p><span class="grp">'+g+'</span><br>Somme :'+s+'</p>';
    }
    
    var randomCard=[];for (var i=0;i<13;i++) randomCard[i]=0;
    for (var i=0;i<5000;i++) {
       var newCards=cards.slice(0);
    	newCards.sort(function(a,b){return Math.random()-0.5});
    	randomCard[Math.floor(newCards[0]/4)]+=1;
    }
    document.getElementById('pge').innerHTML+='<p>Random sort with 0.5 </p>';
    affiche(randomCard);
    
    var randomCard=[];for (var i=0;i<13;i++) randomCard[i]=0;
    for (var i=0;i<5000;i++) {
       var newCards=cards.slice(0);
    	newCards.sort(function(a,b){return Math.random()-0.75});
    	randomCard[Math.floor(newCards[0]/4)]+=1;
    }
    document.getElementById('pge').innerHTML+='<p>Random sort with 0.75 </p>';
    affiche(randomCard);
    var randomCard=[];for (var i=0;i<13;i++) randomCard[i]=0;
    for (var i=0;i<5000;i++) randomCard[Math.floor(Math.floor(Math.random()*52)/4)]+=1;
    document.getElementById('pge').innerHTML+='<p>With random number </p>';
    affiche(randomCard);
    </script>
    </body>
    </html>
    Run this page on IE, Mozilla FireFox, Safari, Opera, to compare the results. Only Google Chrome semms to give uniformly distributed values with the three methods !
    Last edited by 007julien; 06-30-2012 at 06:05 PM.

  • Users who have thanked 007julien for this post:

    meridian (07-01-2012)

  • #10
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    18,318
    Thanks
    203
    Thanked 2,566 Times in 2,544 Posts
    For an unbiased array shuffle routine see

    http://www.codingforums.com/showthread.php?p=1239568 (author Lerura)

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  • Users who have thanked Philip M for this post:

    meridian (07-01-2012)

  • #11
    New Coder
    Join Date
    Jun 2012
    Posts
    26
    Thanks
    25
    Thanked 0 Times in 0 Posts
    Wow. It's amazing the difference between the different methods used. An effective demonstration. Thanks.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •