Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
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 pondering the Monastery: (6)
As of 2024-04-23 07:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found