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.
Page 1 of 2 12 LastLast
Results 1 to 15 of 18
  1. #1
    New Coder
    Join Date
    Aug 2009
    Location
    public_html/cgi-bin/
    Posts
    91
    Thanks
    14
    Thanked 1 Time in 1 Post

    Post Adding random classes from selection

    Hello everyone!

    Been a while since I've come on here, but 2 years of uni later and I am much better at what I do now! However, I'm still no pro though and was wondering if some of the geniuses of codingforums could provide some insight into an issue I have encountered.

    Let's say for example I have an array of different strings that I would like to use as classes.
    eg: classA, classB, classC, classD

    Now let's say I would like a function that applies these classes appropriately. For example:
    Code:
    	function addClasses() {
    		$( ".span4" ).each(function() {
    			// do stuff
    		});
    	}
    The bigger catch is that I want this to be completely randomized and once one of the classes has been added to '.span4' from the array I don't want it repeated.

    So let's say one of the .span4's (there's actually 12 span4's on the page) has classB added to it (randomly selected), none of the other 11 span4's going through the foreach loop are now allowed to pick classB.

    I have an even more difficult barrier directly relating to the same piece of code, but I'll see if anybody could help me out with this problem first - nothing worse than a swamp of questions!

    If anybody is able to provide me with a solution it'll be greatly appreciated. Thanks in advance for any help!

    Kind Regards
    Owen Ayres
    Last edited by Owener94; 07-17-2014 at 11:41 AM.

  • #2
    Regular Coder Lerura's Avatar
    Join Date
    Aug 2005
    Location
    Denmark
    Posts
    946
    Thanks
    0
    Thanked 129 Times in 128 Posts
    Try this:
    Code:
    function shuffle(Arr){
    var NewArr=Arr.slice(0);
      var Range=NewArr.length;
      while(Range>0){
        NewArr.push(NewArr.splice(Math.floor(Math.random()*Range),1)[0]);
        Range--;
      }
      return NewArr;
    };
    
    Classes=['ClassA','ClassB','ClassC','ClassD','ClassE','ClassF','ClassG','ClassH','ClassI','ClassJ','ClassK','ClassL'];
    RandClasses=Shuffle('Classes');
    Elems=document.getElementsByClassName('span4');
    for (Q=0;Q<Elems.length;Q++){
    Elems[Q].className=RandClasses[Q];
    }

  • #3
    New Coder
    Join Date
    Aug 2009
    Location
    public_html/cgi-bin/
    Posts
    91
    Thanks
    14
    Thanked 1 Time in 1 Post
    Thanks for supplying this code. Haven't had the chance to throw it in yet, but after reading it through it seems to make perfect sense. Looks like it will solve the problem!

    Really appreciate that. Thanks again.

  • #4
    New Coder
    Join Date
    Aug 2009
    Location
    public_html/cgi-bin/
    Posts
    91
    Thanks
    14
    Thanked 1 Time in 1 Post
    Hello again,

    I've tried implementing the code as suggested, but I appear to be getting an error thrown my way around the splice part:
    Code:
    NewArr.push(NewArr.splice(Math.floor(Math.random() * Range), 1)[0]);
    It's telling me its undefined. I believe this is because 'NewArr' is not an array at this point, as you've actually selected the first element in Arr and set it as NewArr, which has confused me a tad. Do you think you'd be able to shed some light on that?

    Again, thanks for the help -- proper enjoying coding this stuff at the mo!

    Owen Ayres

  • #5
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,027
    Thanks
    79
    Thanked 4,436 Times in 4,401 Posts
    That shuffle code is badly broken.

    You need *two* new arrays. (Or you can do it with only one new array
    if you don't care that the array you called with is zapped.)

    I vote for keeping the code simple and readable. And not starting
    variable names with upper case letters. Especially local variables.
    Code:
    function shuffle(arr)
    {
        var newArr = arr.slice(0);
        var result = [];
        while(newArr.length > 0)
        {
            var n = Math.floor( Math.random() * newArr.length );
            result.push( newArr[n] );
            newArr.splice( n, 1 );
        }
        return result;
    }
    p.s.: This code actually tested
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #6
    Regular Coder Lerura's Avatar
    Join Date
    Aug 2005
    Location
    Denmark
    Posts
    946
    Thanks
    0
    Thanked 129 Times in 128 Posts
    Quote Originally Posted by Old Pedant View Post
    That shuffle code is badly broken.
    Actually Not.
    Quote Originally Posted by Old Pedant View Post
    p.s.: This code actually tested
    Mine too.
    And it is explained here

    But I made typo:
    Code:
    RandClasses=Shuffle('Classes');
    should have been
    Code:
    RandClasses=shuffle('Classes');

  • #7
    New Coder
    Join Date
    Aug 2009
    Location
    public_html/cgi-bin/
    Posts
    91
    Thanks
    14
    Thanked 1 Time in 1 Post
    UPDATE: I am receiving the error 'uncaught typeerror undefined is not a function' on the splice:
    Code:
    newArr.splice(n, 1);
    Not sure why - am looking into it.

    ---

    Thanks for the input, Old Pedant, as well as Lerura for getting back to me. I still can't seem to get this working and I'm now lost as to why! I've tried implementing both codes supplied, but neither appear to be doing the trick.

    JSFiddle doesn't seem to be chucking any errors either. Here's what I've currently got :-

    Code:
        function shuffle(arr) {
            var newArr = arr.slice(0);
            var result = [];
            while (newArr.length > 0) {
                var n = Math.floor(Math.random() * newArr.length);
                result.push(newArr[n]);
                newArr.splice(n, 1);
            }
            return result;
        }
    
        var bgClasses = ['bg-orange', 'bg-black', 'bg-none', 'bg-green', 'bg-blue', 'bg-brown', 'bg-white', 'bg-yellow', 'bg-purple'];
        var randClasses = shuffle('bgClasses');
    
        var tableCells = document.getElementsByTagName('td');
    
        for (Q = 0; Q < tableCells.length; Q++) {
            tableCells[Q].className = randClasses[Q];
        }
    If it's any help or more efficient - I do have jQuery included already.

    Anything else you can do to help out is greatly appreciated. Thank you!


    Kind Regards
    Owen Ayres
    Last edited by Owener94; 07-20-2014 at 08:25 PM.

  • #8
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,027
    Thanks
    79
    Thanked 4,436 Times in 4,401 Posts
    Okay, I misread Lerura's code. It *does* work. Clever trick, too.

    But your error is obvious:
    Code:
    var randClasses = shuffle('bgClasses');
    WRONG! No quoting wanted.
    Code:
    var randClasses = shuffle(bgClasses);
    Right.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • Users who have thanked Old Pedant for this post:

    Owener94 (07-21-2014)

  • #9
    Regular Coder Lerura's Avatar
    Join Date
    Aug 2005
    Location
    Denmark
    Posts
    946
    Thanks
    0
    Thanked 129 Times in 128 Posts
    That one is on me!
    I have used this function SOOOO many times, but for some reason I added quotes to the solution I gave. Guess I was in too much of a hurry, when replying - and correcting.

  • Users who have thanked Lerura for this post:

    Owener94 (07-21-2014)

  • #10
    New Coder
    Join Date
    Aug 2009
    Location
    public_html/cgi-bin/
    Posts
    91
    Thanks
    14
    Thanked 1 Time in 1 Post
    Thanks to the both of you for your help.

    Can't believe I missed the error too, I was looking at it for some time... shouldn't have slipped past me!

    All working great as I hoped now. Thanks a bunch!

  • #11
    New Coder
    Join Date
    Aug 2009
    Location
    public_html/cgi-bin/
    Posts
    91
    Thanks
    14
    Thanked 1 Time in 1 Post
    Hello again

    Was tempted to create an entirely new thread for this but decided it was appropriate to throw a double-post in here and keep this one going, as it's part of the same code. I'm having troubles and realised I've made a tiny error in what I initially asked too.

    Basically, I want the for loop to allow the selection of multiple classes that is taken from the shuffle function. However, I would like there to be one class within the specified array of classes that can only be included once. All the others can be (and must be) repeated, may I add again.

    I have tried figuring this out for myself, but as soon as I realised other classes need to be repeated (excluding the one that shouldn't be repeated), I got lost!

    I presume what I am suggesting is possible, but is it quite as simple as I had initially asked? If it isn't then I'll feel really guilty and would like to apologise in advance to Lerura and Old Pedant if their efforts have gone unused in my works!

    To anybody new arriving at this post, here is a summary of what I'm looking at:
    I have a selection of containers. The number of containers on each instance varies from anywhere between 2 and 16, let's say. This number is randomly generated upon load. I need each container to have a class applied that is randomly chosen from a selection in a given array of class names. There are roughly 8 classes in this array, let's say. These classes that are being applied to the containers at random can be repeated. However, one of the classes (that I specify) in the array of classes can only be chosen once. It cannot be repeated.

    Any help you can provide would be greatly appreciated again guys. Struggling to figure this one out!

    Kind Regards
    Owen Ayres

  • #12
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,027
    Thanks
    79
    Thanked 4,436 Times in 4,401 Posts
    Pretty easy. Just mark the special class with a leading $ (or other unique character) and then:
    Code:
        var bgClasses = ['$bg-special','bg-orange', 'bg-black', 'bg-none', 'bg-green', 'bg-blue',
                                 'bg-brown', 'bg-white', 'bg-yellow', 'bg-purple'];
        var randClasses = shuffle(bgClasses);
    
        var tableCells = document.getElementsByTagName('td');
    
        for (Q = 0; Q < tableCells.length; Q++) 
        {
            var r = Q % randClasses.length; // if more tableCells than randClasses!!!
            var cl = randClasses[r];  // get chosen class
            if ( cl.charAt(0) === "$" ) // if this is the special once only class...
            {
                cl = cl.substring(1); // zap the $
                randClasses.splice(r,1); // and remove that class from the array
            }
            tableCells[Q].className = cl; // put it in place
            
        }
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #13
    New Coder
    Join Date
    Aug 2009
    Location
    public_html/cgi-bin/
    Posts
    91
    Thanks
    14
    Thanked 1 Time in 1 Post
    Hey Old Pedant

    Thanks for such a speedy response. You're fantastically active on here - it's brilliant!

    This code is working great for everything except one last thing. When there is less table cells than random classes, I still want exactly one random table cell to have the special class. In the current state it seems to be only doing it when there are more than 8 table cells.

    Probably a quick fix, but I'm finding it slightly confusing, as I am not entirely sure how the top lines work I was wondering if you could save the day again!

    Thanks again, you have been a great help to me.

    Kind Regards
    Owen Ayres

  • #14
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,027
    Thanks
    79
    Thanked 4,436 Times in 4,401 Posts
    Well one easy way to do that would be to limit the number of classes BEFORE you do the shuffle.

    So:
    Code:
        var bgClasses = ['$bg-special','bg-orange', 'bg-black', 'bg-none', 'bg-green', 
                         'bg-blue', 'bg-brown', 'bg-white', 'bg-yellow', 'bg-purple'];
        var tableCells = document.getElementsByTagName('td');
    
        if ( tableCells.length < bgClasses.length ) 
        {
            bgClasses.splice( tableCells.length ); // shrink classes to match
        }
        var randClasses = shuffle(bgClasses);
    
    
        for (Q = 0; Q < tableCells.length; Q++) 
        {
            var r = Q % randClasses.length; // if more tableCells than randClasses!!!
            var cl = randClasses[r];
            if ( cl.charAt(0) === "$" ) // if this is the special once only class...
            {
                cl = cl.substring(1); // zap the $
                randClasses.splice(r,1); // and remove that class from the array
            }
            tableCells[Q].className = cl; // put it in place
            
        }
    But that will always lop off the last listed classes.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #15
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,027
    Thanks
    79
    Thanked 4,436 Times in 4,401 Posts
    I think this works to pick a random set of non-specials classes. Beginning to get more complex. Code is UNTESTED.
    Code:
        // notice that bgClasses does *NOT* now include the special class
        var bgClasses = ['bg-orange', 'bg-black', 'bg-none', 'bg-green', 
                         'bg-blue', 'bg-brown', 'bg-white', 'bg-yellow', 'bg-purple'];
        var randClasses = shuffle(bgClasses); // so randClasses has no special class in it
    
        var tableCells = document.getElementsByTagName('td');
    
        if ( tableCells.length - 1 < bgClasses.length ) // notice the -1 ... to account for missing special class
        {
            bgClasses.splice( tableCells.length - 1 ); // shrink classes to match
        }
        bgClasses.push('$bg-special'); // *NOW* add in the special class
    
        randClasses = shuffle(randClasses); // re-shuffle, now with the special class in there
    
    
        for (Q = 0; Q < tableCells.length; Q++) 
        {
            var r = Q % randClasses.length; // if more tableCells than randClasses!!!
            var cl = randClasses[r];
            if ( cl.charAt(0) === "$" ) // if this is the special once only class...
            {
                cl = cl.substring(1); // zap the $
                randClasses.splice(r,1); // and remove that class from the array
            }
            tableCells[Q].className = cl; // put it in place
            
        }
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.


  •  
    Page 1 of 2 12 LastLast

    Posting Permissions

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