The Modulo Operator for Alternating Rows

One common design feature is to have different visual treatments for alternating rows. As you iterate through a collection, you can use the modulo operator to determine if you're in an even or odd row.

In most languages, the modulo operator is the percent sign: %. Here's a quick example in PHP:

for($i=0;$i<10;$i++)
{
  if($i % 2)
  {
   // I'm in an even row
  }else{
   // I'm in an odd row
  }
}

The modulo is the remainder of doing a division. Dividing by 2 will have a remainder of only 0 or 1.

Published September 01, 2005 · Updated September 14, 2006
Categorized as PHP
Short URL: https://snook.ca/s/410

Conversation

49 Comments · RSS feed
Peter Parkes said on September 01, 2005

Now why had I never thought of that before?

Still, I'd probably use it like this:

for($i=0; $i<10; $i++)
{
    $class = 'row' . ($i % 2);

    // code in here
}

and then define .row0 and .row1 in my stylesheet.

Adam Thody said on September 01, 2005

Wow...that's a hell of a lot easier than the way I've been doing it all these years.

Although using Smarty on most projects lately has simplified things.

Good tip!

Chris said on September 01, 2005

Amazingly simple...how come I didn't think of that?

Justin P said on September 01, 2005

The modulus operator has been a handy odd/even determination tool for a very long time, I'm a little shocked people are only recently finding out about it (around here anyway).

Btw, it's not just for odd/even. You can do all sorts of cool stuff like figure out if it's a leap year, or any other repeating pattern like that.

flevour said on September 01, 2005

Justin: I think you shouldn't be surprised for this. PHP has made it possible for a lot of non-programmers to easily create scripts. This is great because it helped spreading PHP all over the world, but it has been also a bad thing because it allowed the creation of bad-written scripts (personally I have been in the second category for long time). Therefore for me it's not surprising most people don't know about some simple PHP (dare I say programming) things like the modulus operator.

Justin P said on September 01, 2005

Very true flevour, I guess I lucked out. When I was a total newbie to server-side programming this was one of the first things that was taught to me (when I took a server-side programming class) so we could alternate row background colors.

Chris Lienert said on September 01, 2005

I'm feeling very clever at having used this method for years.

What's the point in declaring a class for each row? Only the odd rows need a class to mark the exception e.g.
css:
table tr td {
  background-color: #000;
  color: #FFF;
}
table tr.alt td {
  background-color: #FFF;
  color: #000;
}

html:
<table>
<tr>...</tr>
<tr class="alt">...</tr>
</table>

said on September 01, 2005

There was nothing in the original post about putting a class on each row. Putting "alt" or something in every other row is pretty much standard.

Andrei Maxim said on September 02, 2005

Coming from ASP.NET, you code looks like hacking. In my web development world, there are simpler solutions.

For example, if we have a DataGrid (or table with a database behind, for those that aren't familiar with the ASP.NET slang), we'd have to write only:

DataGrid1.AlternatingItemStyle.CssClass = "alterRow";
Jonathan Snook said on September 02, 2005

Andrei: ASP.NET is simply an application framework. The underlying language still needs to determine alternate rows. Using Reflector on the CreateControlHierarchy of the DataGrid object reveals these couple lines of code:

else if ((num6 % 2) != 0)
   {
       type1 = ListItemType.AlternatingItem;
   }

As you can see, even Microsoft uses the modulo.

Miha said on September 02, 2005

What about this?

for ($i=0; $i<10; $i++) {
	echo (($i % 2 == 0) ? 'even' : 'odd');
}

I don't like to write a lot of unnecessary code as you can see :)

Miha said on September 02, 2005

Em, I guess there seems to be something wrong with my comment. It eats up almost everything I write within the pre and code tags. What gives?

Jonathan Snook said on September 02, 2005

You have to remember to encode your <s and >s. :) I removed the duplicate post and fixed the encoding in your first comment.

Ryan Brooks said on September 02, 2005

I'm with Miha - using an operator with your PHP is much easier, and it's actually faster in my benchmarks.

Richard@Home said on September 02, 2005

This one is taken from the PHP manual:

$colours = array('#000000', '#808080', '#A0A0A0', '#FFFFFF');

// Get a colour
$color = next($colors) or $color = reset($colors);

(This example uses 4 colours)

nuffGigs said on September 02, 2005

I use this operator all the time in JavaScript to figure out leap year. Never thought about using it for alternate rows. Great tip!!

Andrei Maxim said on September 02, 2005

Jonathan, I was trying to show how sometimes things can be really simple on a not so popular platform (compared to LAMP).

There's nothing wrong (or degradating) with the modulo operator as far as I'm interested and I've used it plenty of times.

I woder if there is such thing as shifting in PHP. I remember that it was considered a better solution than using the modulo operator when speed was really an issue.

Miha said on September 02, 2005

Thanks Jonathan :)

David House said on September 05, 2005

A quick note on the logic: if you want to test for an even number, you need to do if (!$i % 2). If you want to test for an odd number, you need to do if ($i % 2).

When first looking at Jonathan's code, I thought he'd got the logic the wrong way round. However, he sneakily started $i at 0, so when $i is 0, we're on the 1st row. Thus an even $i means an odd row number. So the logic needs to be backwards.

Duncan said on September 05, 2005

It is certainly true that the modulo operator is '%' in most languages but making the assumption that 'most' means 'all' cost we about half an hour when, earlier in the week, I was trying to write the folowing code:


<xsl:for-each select="list/item">
  <xsl:if test="position() mod 2 = 1">
    <xsl:attribute name="class">odd</xsl:attribute>
  </xsl:if>
</xsl:for-each>
Jonathan Snook said on September 05, 2005

Duncan: yeah, I said most on purpose because I know that, for example, VBScript uses Mod. Great use of the mod operator in XSLT, btw.

Aleksandar said on September 06, 2005

Man...I read through all the comments and I can't believe how complicated things people use.

$nBgColor = 0

and then in the loop:

$nBgColor = 1 - $nBgColor

and use classes like row0 and row1 on tr. Subtraction is the fastest operation you can get.

Wesley Walser said on September 09, 2005

I am with Justin P on this one. That was one of the first operators that we looked at 3 years ago in my first CS class.

Jonathan Snook said on September 09, 2005

Wesley: I actually sat on the fence about posting this because it seems pretty basic but as I have discovered previously, you can't assume everybody knows the same tricks you do. Not everybody learns to program through a computer science class. (I didn't... I just happened to learn from people who did!)

mario said on September 13, 2005

so coldfusion use the mod operator:

<cfset farbe=iif(counter mod 2, de("333333"), de("666666"))/>
Michiel said on September 14, 2005

Heh, funny thing, I just explained this to a coworker. She didn't know about it and I was like: "What?!How can you not know this stuff??". And she was always saying how good she was at writing webapps in PHP...

nader said on November 16, 2005

i'm actually not a programmer so sorry if it might sound stupid.

i have a blog where i display cool ads from companies.

3 pictures per row and i want to have a

tr>/tr>

after every 3rd pic in a row.

you can check it out at www.brandinfection.com/ads

at the moment i'm using if($count == 3 || $count == 6...

very very silly i know but somehow this modulo thing doesn't work or i have to write it differently?

please help.

thanks a lot, nader

Justin P said on November 16, 2005

Hey nader,
You could probably do something like this:

if ($count % 3) {
/* The count is divisble by 3 evenly */
} else {
/* The count is not evenly divisible by 3 */
}

jacopo said on December 09, 2005

hi,

this script can also be written with bitwise operator '&', much faster than '%'.

for($i=0;$i<10;$i++){
if(1 & $i){
// I'm in an odd row
}
else{
// I'm in an even row
}
}

jacopo said on December 09, 2005

errata corrige:

for($i=0;$i<10;$i++){
if(1 & $i){
// I'm in an odd row
}
else{
// I'm in an even row
}
}

jacopo said on December 09, 2005

you improve the code of your 'post comment'.
seems to not like this:
$i<10;$i++

($i<10;$i++)

said on December 27, 2005

$n = 0; // row counter

while ($row = mysql_fetch_array($result))
{
$n++;
$n = $n&1;
print "<tr class=\"row$n\">
// et cetera

Kris Olhovsky said on January 03, 2006

This code is probably slightly faster, if not quite as clean:

for($i=0;$i<10;$i++)
{
$j = (1 == $i) ? 0 : 1;
$class = 'row' . $j;
// code in here
}

This causes $j to 'flip' back and forth from 0 to 1 (in this case, starting with 1). To change $j from 0 to 1 it does a simple comparison, whereas doing a modulus calculation takes slightly more effort.

-- Kris Olhovsky

Kris Olhovsky said on January 03, 2006

Nevermind, Aleksandar's method of subtraction is the best way.
(Fastest and still simple).

$nrow = 0;
for($i=0;$i<10;$i++){
   $nrow = 1 - $nrow;

   $class = 'row'.$nrow;
   //code in here
}
justin said on January 04, 2006

I use this technique:

// using a for loop
for($i=0;$i<10;$i++){
echo $i%2 ? 'odd' : 'even';
}

// using a while loop
$i = 0;
while(condition){
echo $i++%2 ? 'odd' : 'even';
}

Dylan Anderson said on April 27, 2006

If you're using classes, this is what I use:

while(loopingThroughWhatever)
{
$class = ($class == 'even') ? 'odd' : 'even';
}

Justin said on May 18, 2006

To get something like this:
<div class="row_0">...</div>
<div class="row_1">...</div>
<div class="row_0">...</div>
<div class="row_1">...</div>

Using PHP, I use this method:
<?php
$num_classes = 2;
$i = 0;
while(condition){
?>
<div class="row_<?php echo $i++%$num_classes; ?>">...</div>
<?php } ?>

I like this method because it supports any number of alternating rows. Change '$num_classes' to however many alternating row classes you want.

Tim said on June 26, 2006

Just a quick idea: Since this is a matter of frontend, I do the "odd-even"-thing with javascript. Just add to the className of every table-row an " odd" or " even" to make them show the way you want them.

Doing it the JS-way is pretty cool, because you don't have to worry in every loop on determing the row you are in. I use "moo.dom" to do the DOM-Exploring.

Just a thought!

Patrick said on October 27, 2006

Thanks - Nice Tip!

Jon said on November 03, 2006

This is how I do it:


foreach...
{
     echo 'class="row'.($i ++ % 2 + 1).'"';
}

Gives you classes of row1, row2, row1...

Mike said on December 29, 2006

Lots of short-hand methods and ternary operator examples given here, both are bad. You should always break down your conditional statements using curly braces for a couple of reasons..

1. It's more readable
2. If you ever need to do something else with that statement, it's easy to drop additions in (such as an 'elseif')

I only say this because like others, I've been using modulus for years, and there are times when I've had to go back and alter logic.

Jonathan Snook said on December 29, 2006

Mike: although I used an if/else statement in my example, I'm certainly not against using the ternary operator or other shorthand methods.

From a readable POV, it's marginal. From a refactoring POV, code refactoring happens and a ternary operator is barely going to slow me down and doesn't happen that very often.

Woody C said on February 12, 2007

I often have foreach loops in my PHP, and use associate arrays instead of numeric ones.

I personally think foreahcloops and assoc arrays are much more readable, so I prefer the example by Richard@Home, which doesn't require a numeric loop counter.

Rick Wong said on March 27, 2007

Too bad that my comment is at the bottom of the page, but oh well..

You know what's even faster than modulo? The logical and-operator.

for($i=0; $i<100; $i++) {
  echo 'odd: ' . (($i & 1) ? 'yes':'no');
}

However, it only works on powers of two. Just substract 1 from a power of two (2-1) 1, (4-1) 3, (8-1) 7, etc.
It should be faster than modulo, even just a little bit. ;)

- Lick

Curtis J. Morley said on April 01, 2007

Great example. This is very similar in Actionscript. Here is the code -


var myRow:Object = new Object;
var color0:Number = 0x0000ff;
var color1:Number = 0x00ff00;
for(var i:Number=0; i<10; i++)
{
	myRow.rowColor = _root["color"+(i % 2)];
	trace(myRow.rowColor);
}

var myRow:Object = new Object;
for(var i:Number=0; i<10; i++)
{
	i % 2 == 0 ? myRow.rowColor = 0xff00ff : myRow.rowColor = 0xff0000;
	trace(myRow.rowColor);
}
Lakshmi Mareddy said on May 08, 2007

I use wordpress to run my blog. I initially used the mod approach for alternating rows. i went greedy, thinking, what about if I want say 4 styles...and each output to be displayed as floats ? So i came up with this.. You can extend the logic however...
Till a month ago I had this code in my theme, when I changed the skin again...


<?php
if (have_posts()) :
$post = $posts[0];
$styleno=1;
while (have_posts()) : the_post();
$floatclass = ('righthalf' == $floatclass) ? 'lefthalf' : 'righthalf';
?>
<div class="<?php echo $floatclass; ?>">
<?php if($styleno==5){$styleno=1;} ?>

	<div class="style<?php echo$styleno;?>">
	<!--  Whatever Needs to be displayed -->
	</div>

</div>
<?php $styleno++; ?>
<?php endwhile; ?>
<?php endif; ?>
BenW said on August 17, 2007

Hi there,
I'm a switch junky so I have been using this:


function colors($i, $s1, $s2)
{
	switch($i%2)
	{
		case 0:
		return $s1;
		break;
		case 1: default:
		return $s2;
		break;
	}
}
// Working example. Could use classes too but that's
// too much for this post ;)
$s = '';
$i = 0;
$data = range('A','Z');
$s ='<table>';
while($i < count($data))
{
    $s.='
    <tr style="background-color:'.colors($i,'#DCDCDC','#B0C4DE').';"><td>
    '.$data[$i].'
    </td></tr>';
$i++;
}
echo $s.'</table>';


in conjunction with a loop for years. I never did a benchmark between conditionals and switches. Anyways looks like this subject was beat to heck but I thought I would share anyways. P.S. This should work out of the box. Bye.

Paul Decowski said on September 11, 2007

I prefer oneliners:


$class = $class ? '' : ' class="odd"';


And then:


echo "<tr$class>";

Erik said on November 10, 2011
<li>
	<xsl:if test="position() mod 2">
		<xsl:attribute name="class">even</xsl:attribute>
	</xsl:if>
	...
</li>

position() works in for-each loops. In recursive loops it would be passed as a template param.

Sorry, comments are closed for this post. If you have any further questions or comments, feel free to send them to me directly.