Helper Methods for Working with Arrays

January 23, 2011

This post is just some quick functions that can help you in working with arrays. These are especially helpful when working with document oriented databases such as MongoDB where the schema may not always be consistent between data.

Array Element

When working with nested arrays it helps to be able to dive into the data and provide a fallback if the element you want does not exist. It allows you to dive as far as you want into an array by using a dot notation.

<?php

function array_element($array, $key, $default = false)
{
    $key = explode('.', $key);
    if(count($key) > 1)
    {
        if ( ! is_array($array) || ! array_key_exists($key[0], $array))
        {
            return $default;
        }
        $array = $array[$key[0]];
        unset($key[0]);
        $key = implode('.', $key);
        $array = array_element($array, $key, $default);
        return $array;
    }
    else
    {
        $key = $key[0];
        if ( ! is_array($array) || ! array_key_exists($key, $array))
        {
            return $default;
        }
        return $array[$key];
    }
}

For example if you wanted to access address information inside of an array you might do the following.

<?php

// Input array

$user = array(
'name' => 'Bob Smith',
'age' => 43,
'address' => array(
    'city' => 'Houston',
    'state' => 'TX',
    ),
);

// Grab the City or use the Default of 'Unknown City'

$city = array_element($user, 'address.city', 'Unkown City');

Array Sort

This function allows you to sort an array by the value of any of the array's subelements. It works in conjunction with the array_element() function above so you can sort deep within arrays.

<?php

function array_sort($array, $key, $order = 'asc', $sort_flags = SORT_REGULAR)
{
    if( ! is_array($array))
    {
        return FALSE;
    }

    foreach($array as $k=>$v) 
    {
        $b[$k] = array_element($v, $key);
    }

    switch($order)
    {
        case 'asc':
            asort($b, $sort_flags);
        break;

        case 'desc': 
            arsort($b, $sort_flags);
        break;
    }

    foreach($b as $key=>$val) 
    {
        $c[$key] = $array[$key];
    }

    return $c;
}

Here is the example of how you may use this sort function with nested arrays.

<?php

$data = array(
    array(
        'info' => array(
            'pet' => array(
                'type' => 'dog'
            )
        ),
    ),
    array(
        'info' => array(
            'pet' => array(
                'type' => 'fish'
            )
        ),
    ),
    array(
        'info' => array(
            'pet' => array(
                'type' => 'cat'
            )
        ),
    ),
);

$data = arr::sort($data, 'info.pet.type');
// Returns
array(
    array(
        'info' => array(
            'pet' => array(
                'type' => 'cat'
            )
        ),
    ),
    array(
        'info' => array(
            'pet' => array(
                'type' => 'dog'
            )
        ),
    ),
    array(
        'info' => array(
            'pet' => array(
                'type' => 'fish'
            )
        ),
    ),
);

Just so you know I have contributed both of these functions to FuelPHP's array class. If you have not heard of FuelPHP I recommend it highly as it borrows some of the best ideas from CodeIgniter, Kohana, and Rails. Thats really it. Let me know what you think in the comments.

Monitor your DNS Zones with ZoneWatcher

Be alerted of DNS record changes moments after they happen, not from upset customers.

ZoneWatcher screenshot