SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Member
    Join Date
    Nov 2009
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    random message with no repeats

    im trying to display a random number, but each time a button is pressed that calls the test function, i don't want to random number to be repeated. i know i have to declare 2 variables and a while loop, but i'm stuck as to what to put in the second variable and in the while loop. any advice is appreciated

    var random = Math.floor(Q * Math.random());
    var random2 = ??

    function test () {
    document.write(random);

    while (random == random2) {
    document.write(random);
    }
    }

  2. #2
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Is it a message or the actual random number you're outputting? If it's one message in an array, I'd shuffle the array first, then display each message in order. Since they'll be in a random order already, you can go through them one after the other.

    Code javascript:
    function shuffle(ary) {
      function randOrd(){return (Math.round(Math.random())-0.5); }
        ary.sort( randOrd );
    }
    From here

    You would just need to loop through your array of messages after applying shuffle() to it.

    If you just want to output the random number, then you have to keep an array of used numbers.
    Code javascript:
    var used = [];
    function show_unique_random(Q) {
      var random = Math.floor(Q * Math.random());
      if (used[random] === true) return show_unique_random(Q);
      else {
        used[random] = true;
        return random;
      }
    }
    I assume Q is some integer to limit the range of the random numbers. If it is too enormous, then the method above is not suitable. How bit is it?

    By the way, you should not be using document.write.

  3. #3
    Function Curry'er JimmyP's Avatar
    Join Date
    Aug 2007
    Location
    Brighton, UK
    Posts
    2,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If it's whole random integers that you're after, then try this:

    Code JavaScript:
    var generateRandomNumber = (function(){
     
        var used = {};
     
        return function(min, max) {
     
            min = min || 0;
            max = max || 9999999;
     
            var i, attempts = 0;
     
            while ( used[i = Math.floor(Math.random() * (max - min + 1) + min)] ) {
                if ( attempts++ > max-min ) {
                    return null;
                }
            }
     
            used[i] = true;
            return i;
     
        };
     
    })();
     
    // Usage:
     
    generateRandomNumber(0, 500); // Between 0 and 500, never the same one twice

    Also, this function will return null if all numbers have been used already.
    James Padolsey
    末末末末末末末末末末末末末末末末末末末
    Awesome JavaScript Zoomer (demo here)
    'Ajaxy' - Ajax integration solution (demo here)

  4. #4
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Good idea to return null, mine throws an error (infinite recursion) when they've all been exhausted. Should have tested it first!

    Every time I see something like this I struggle to see why (in this case) used doesn't get trashed after each call to generateRandomNumber. I know it's because of the closure it's in, but I've never felt like I fully grasp the idea. I just make objects and assign properties, which seems so much more boring now.

  5. #5
    Function Curry'er JimmyP's Avatar
    Join Date
    Aug 2007
    Location
    Brighton, UK
    Posts
    2,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Raffles View Post
    Every time I see something like this I struggle to see why (in this case) used doesn't get trashed after each call to generateRandomNumber. I know it's because of the closure it's in, but I've never felt like I fully grasp the idea. I just make objects and assign properties, which seems so much more boring now.
    I had trouble fully grasping it at first, but eventually got used to it. I think it helps to think of every function as an environment in which variables are retained as long as they're required.

    Creating a function inside a another function means that it will have access to all the variables within its "parent's" scope, and it can change those variables as it sees fit. So:

    Code JavaScript:
    var increment = (function(){
        var i = 0;
        return function() {
            return ++i;
        };
    })();
     
    increment(); // 1
    increment(); // 2
    increment(); // 3
     
    // i is changed within the parent scope, each time the inner function
    // is called it accesses and increments the *current* value of i


    More reading:

    James Padolsey
    末末末末末末末末末末末末末末末末末末末
    Awesome JavaScript Zoomer (demo here)
    'Ajaxy' - Ajax integration solution (demo here)

  6. #6
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Before you posted that, I did some looking of my own. This one phrase made things 'click': "a function is executed in the scope in which it was defined" - from JavaScript: the definitive guide (O'Reilly). The bit of where it is defined is what helps the most.

    Thanks for the links - that first one is pretty comprehensively enormous. I'll have a look at them all when I have some more time.


Bookmarks

Posting Permissions

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