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.

No comments:

Post a Comment