Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Odd and even table rows

by Anonymous Monk
on Aug 08, 2007 at 12:39 UTC ( [id://631297]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!
This code is to print different colors on a table row, I would like to know is there is a better way off doing this or if this code is a overkill.

my $i=0; my $mod=0; my $class; while ($pointer = $sth->fetchrow_hashref) { $mod=($i % 2); if($mod == 0) { $class="even"; }else { $class="odd"; } $i++; ...more stuff goes here.... }


Thanks a lot!

Replies are listed 'Best First'.
Re: Odd and even table rows
by moritz (Cardinal) on Aug 08, 2007 at 12:51 UTC
      or even $class = $i % 2 ? 'odd' : 'even'; - I use this often enough that I think it's clear what's happening without the explicit == 0
Re: Odd and even table rows
by brian_d_foy (Abbot) on Aug 08, 2007 at 15:35 UTC

    I got tired of doing this all the time, so I created Tie::Cycle. Every time I use the tied scalar, it advances itself along its possible values:

    use Tie::Cycle; tie my $cycle, 'Tie::Cycle', [ qw( even odd ) ]; foreach my $row ( 0 .. 6 ) { print qq|<tr class="$cycle">...</tr>\n|; }

    In the output, it flip flops between "odd" and "even".

    <tr class="even">...</tr> <tr class="odd">...</tr> <tr class="even">...</tr> <tr class="odd">...</tr> <tr class="even">...</tr> <tr class="odd">...</tr> <tr class="even">...</tr>

    It gets better when you want to cycle through more values. Just add them to the call to tie:

    use Tie::Cycle; tie my $cycle, 'Tie::Cycle', [ qw( red white blue ) ]; foreach my $row ( 0 .. 6 ) { print qq|<tr class="$cycle">...</tr>\n|; }
    --
    brian d foy <brian@stonehenge.com>
    Subscribe to The Perl Review
Re: Odd and even table rows
by Fletch (Bishop) on Aug 08, 2007 at 12:52 UTC

    Not necessarily overkill in as that's pretty much what any such scheme is going to boil down to underneath; however it's certainly more verbose than it needs to be.

    my $ctr = 0; my $class; while( $pointer = $sth->fetchrow_hashref ) { $class = ( ($ctr++) % 2 == 0 ) ? "even" : "odd"; ## ... }

    Alternately there are JavaScript libraries which will go in and post-facto class-er-ize tables dynamically (which is nice if you're doing some Ajax fanciness and possibly reordering rows on the fly).

      or a little less verbose and (imho :) ) even more readable:

      my $odd; my $class; while( $pointer = $sth->fetchrow_hashref ) { $class = ($odd ^= 1) ? "odd" : "even"; ## ... }

      DWIM is Perl's answer to Gödel
Re: Odd and even table rows
by johnlawrence (Monk) on Aug 08, 2007 at 13:31 UTC
    You don't actually need to do most of that, all you really need is to swap the value each time...
    my $class = "even"; while ($pointer = $sth->fetchrow_hashref) { $class = ($class eq "odd") ? "even" : "odd"; ...more stuff goes here.... }
Re: Odd and even table rows
by citromatik (Curate) on Aug 08, 2007 at 12:58 UTC

    A less verbose way of doing the same thing would be:

    my $i=0; while ($pointer = $sth->fetchrow_hashref){ my $class = ("even","odd")[$i++%2]; ...more stuff goes here.... }

    citromatik

      Or a variation on yours and GrandFather's replies:
      my $t; while ($pointer = $sth->fetchrow_hashref){ my $class = qw(even odd)[$t^=1]; ... }
      - Miller
Re: Odd and even table rows
by duff (Parson) on Aug 08, 2007 at 13:41 UTC

    Just as another way to do it ... if you know the browsers support it, you can use the "odd" and "even" selectors:

    tr:nth-child(odd): ... tr:nth-child(even): ...
    Yes, this probably isn't as useful today as it will be 5 years from now :(
Re: Odd and even table rows
by ikegami (Patriarch) on Aug 08, 2007 at 15:58 UTC
    Yet another way.
    my @classes = qw( odd even ); while (...) { push @classes, my $class = shift @classes; ... }

    Here's a collection of alternatives, including those already presented:

    All code snippets tested except the one using Tie::Cycle.

    Update: Added wind's solutions.

Re: Odd and even table rows
by wind (Priest) on Aug 08, 2007 at 18:31 UTC

    The first method I ever used for this was an alternating hash.

    my ($class, %flip_class) = qw(odd odd even even odd); while (...) { $class = $flip_class{$class}; ... }
    or using a slightly obfuscated definition. It even saves 2 characters! :)
    my ($class, %flip_class) = qw(odd even)[0,1,0,0,1]; while (...) { $class = $flip_class{$class}; ... }
    Another way I just thought of would be to use grep.
    my $class = 'odd'; while (...) { ($class) = grep {!/$class/} qw(odd even); ... }

    Personally, I'd probably stick with a bitwise xor ^, but any of these monastery solutions would work just fine.

    - Miller

Re: Odd and even table rows
by andreas1234567 (Vicar) on Aug 08, 2007 at 18:01 UTC
    This (w3.org) document says you can use Cascading Style Sheets directly without setting the style element:
    tr:nth-child(even) {background: #CCC} tr:nth-child(odd) {background: #FFF}
    Untested, and see warning on browser support.

    --
    Andreas
      According to this comparison chart, nothing really supports this CSS 3 pseudo-class yet. It may be that recent nightly builds of Firefox or some other OSS browser would have support, but I'd doubt it.
Re: Odd and even table rows
by wagemage (Initiate) on Aug 08, 2007 at 22:41 UTC
    Well, this is my very first perlmonks reply, but a slightly more terse approach would be
    $class=$i++%2?"odd":"even";
    
    Though I'm sure plenty of people will point out better ways
Re: Odd and even table rows
by Moron (Curate) on Aug 09, 2007 at 09:54 UTC
    My first thought was:
    our $flipflop = !1; our %class = ( $flipflop => 'even', !$flipflop => 'odd' ); sub getclass { $class{ $flipflop = !$flipflop }; }
    The '!' in the initialisation values are to avoid reliance on specific truth values so they can be used safely as hash keys for any given Perl implementation.

    update: in practice I'd use an instance variable instead of a class variable for $flipflop, but before that I'd have to do OO makeover of the OP which I avoided doing.

    __________________________________________________________________________________

    ^M Free your mind!

    .

Re: Odd and even table rows
by DrHyde (Prior) on Aug 09, 2007 at 09:50 UTC
    I tend to think that this is a presentation issue, and so should be handled by your front-end code, such as your templating engine. Don't put it in your database access code.
Re: Odd and even table rows
by Anonymous Monk on Aug 10, 2007 at 18:08 UTC
    If you do not need the value of $i, you could use the XOR operator:
    $i = 0 for( $j = 0; $j < 10 ; $j++ ) { if( $i == 0 ) { $class = "even" ; } else { $class = "even" ; } $i ^= 1 ; }
    Or you could toggle $i between two values:
    $i = 1 ; for( $j = 0; $j < 10 ; $j++ ) { $i *= -1 ; if( $i == -1 ) { $class = "even" ; } else { $class = "even" ; } }
    Or you could just flip the value of $class:
    if( $class =~ /even/ ) { $class = "odd" ; } else { $class = "even" ; }
    Or
    $class = ( $class ~= /even/ ) ? "odd" : "even" ;

    Enjoy
    Keith
Re: Odd and even table rows
by pemungkah (Priest) on Aug 13, 2007 at 06:21 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://631297]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2024-04-18 18:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found