Friday, 9 July 2010

Array Arrange By Function

PHP has a fantastically useful range of functions for handling Arrays. I found that there were a couple of situations that I was habitually facing which they didn't handle. These related to 2D arrays returned by SQL that I needed to rearrange in different ways. The first function is Array_Arrange_By() and is shown below:
function Array_Arrange_By($arr, $key, $key2 = null) {
      $out = array();
      if (!$arr) {
          return $out;
      }
      foreach ($arr as $k => $row) {
          if (is_array($key2)) {
              @$out[$row[$key]][] = $row;
          } else if ($key2) {
              $out[$row[$key]] = $row[$key2];
          } else {
              $out[$row[$key]] = $row;
          }
      }
      return $out;
}
This function will reindex this array in one of 3 ways:
array([0] => array('id' => 1,'b' => 'dog','cst' => 20),
      [1] => array('id' => 4,'b' => 'cat','cst' => 60),
      [2] => array('id' => 8,'b' => 'cat','cst' => 80),
      [3] => array('id' => 9,'b' => 'cat','cst' => 90));

var_export (Array_Arrange_By($a, 'id'));

Gives:

array (
  1 => 
  array (
    'id' => 1,
    'type' => 'dog',
    'cst' => 20,
  ),
  4 => 
  array (
    'id' => 4,
    'type' => 'cat',
    'cst' => 60,
  ),
  8 => 
  array (
    'id' => 8,
    'type' => 'cat',
    'cst' => 80,
  ),
  9 => 
  array (
    'id' => 9,
    'type' => 'cat',
    'cst' => 90,
  ),
)
It's very useful as the array returned contains the same information but is indexed by the 'id' field. Alternatively you might only want one of the non-id fields from the original array.
array([0] => array('id' => 1,'type' => 'dog','cst' => 20),
      [1] => array('id' => 4,'type' => 'cat','cst' => 60),
      [2] => array('id' => 8,'type' => 'cat','cst' => 80),
      [3] => array('id' => 9,'type' => 'cat','cst' => 90));

print_r (Array_Arrange_By($a, 'id', 'type'));

Giving:

array (
  1 => 'dog',
  4 => 'cat',
  8 => 'cat',
  9 => 'cat',
)
This might be a very useful lookup array. Finally sometimes you may want to perform the equivalent of a PHP level group by operation.
array([0] => array('id' => 1,'type' => 'dog','cst' => 20),
      [1] => array('id' => 4,'type' => 'cat','cst' => 60),
      [2] => array('id' => 8,'type' => 'cat','cst' => 80),
      [3] => array('id' => 9,'type' => 'cat','cst' => 90));

print_r (Array_Arrange_By($a, 'type', array()));

Gives:

array (
  'dog' => 
  array (
    0 => 
    array (
      'id' => 1,
      'type' => 'dog',
      'cst' => 20,
    ),
  ),
  'cat' => 
  array (
    0 => 
    array (
      'id' => 4,
      'type' => 'cat',
      'cst' => 60,
    ),
    1 => 
    array (
      'id' => 8,
      'type' => 'cat',
      'cst' => 80,
    ),
    2 => 
    array (
      'id' => 9,
      'type' => 'cat',
      'cst' => 90,
    ),
  ),
)
This array gives a really nice way to now generate a 2 Level table. In this case iterating through the different types and then each of the records with that type.

Test Page for Syntax Highlighting

I've been unsatisfied in the past about the results of posting code onto this blog in the past and I've long been meaning to add Syntax Highlighting to make it look better. Happily someone else has done the hard work. Thank you Alex for SyntaxHighlighter.
/**
* SyntaxHighlighter
*/
function foo()
{
  if (counter = 10)
      return;
  // it works!
}