Wednesday, November 23, 2011

Nitty Gritty PHP

Well here's an interesting PHP lesson for you: there's an interesting trick to finding a count of the number of items in the second dimension of a two-dimensional array.  Say you have an array like:


$arr = array(
  "1"=>array(
      "red"=>1,
      "blue"=>2
  ),
  "2"=>array(
      "green"=>3,
      "yellow"=>4
  )
);

A totally contrived example, but count($arr) = 2 here, and we can use the recursive flag to arrive at count($arr, COUNT_RECURSIVE) = 6.

So the trick to figuring out how many second-level items I have is to just do count($arr, COUNT_RECURSIVE) - count($arr) = 6-2 = 4.

Of course, one could do something like

$count = 0;
foreach($arr as $key=>$value)
{
  foreach($value as $innerKey=>$innerValue)
  {
     $count++;
  }
}

And arrive at 4 as well.

So let's say you have an array where those colors point to stdClass objects.  All well and good, right?  Right - COUNT_RECURSIVE halts at the second dimension, and properly counts the objects.  Now let's say you have a multi (more-than-2)-dimensional array, such as:


$arr = array(
  "1"=>array(
      "red"=>array(1,2,3),
      "blue"=>array(4,5,6)
  ),
  "2"=>array(
      "green"=>array(1,2,3),
      "yellow"=>array(4,5,6)
  )
);

This is possible if you convert your stdClass objects into arrays when loading them into each color index. Of course, our nested foreach loops will still work, but what happens with COUNT_RECURSIVE?

Now, the count doesn't stop at the 2nd dimension - it recurses all the way down through the arrays.  Now you get count($arr, COUNT_RECURSIVE) - count($arr) = 18-2 = 16, a far cry from the 4 that we wanted.

Lesson learned.