Navigating Associative Arrays

When you are processing a regular array it is relatively straightforward to get the previous or next element of the array simply by subtracting or adding one to the array index. When you have an associative array the elements are presumed to be completely independent of each other without any particular order and so getting the previous or next entry is presumed to have no meaning. This isn't always true though, it is quite possible for you to have an associative array where the order that the entries are in also has meaning.

Where this applies you have the not so straightforward task of working out how to retrieve the previous or next element of the array when you know what the key of the current element is. The most obvious way is to simply read through the array from the start retrieving each key value in turn. When you retrieve the desired key then you know that the one you retrieved immediately prior to that is the prior key and that retrieving the following key will give you the one that comes next. Performing this task every time means that you are constantly reading and rereading large sections of the array. We can avoid all of this reading and rereading by creating an array of just the keys that we can then process as a regular array. In order to be able to do the initial key lookups on this array we also need a copy of the original associative array but with the numerical positions in the array replaced by the numerical position of the entry within the array.

We can create both of these new arrays by first calling array_keys() to get the array of just the keys and then passing that to array_flip() to create the new associative array. Of course doing this is quite a significant overhead so if we are planning on doing lots of previous and next lookups on an associative array then ideally we want to create these extra arrays just once and then be able to do all of the lookups using these extra arrays. The following class allows you to do just that. Creating a new object belonging to the AssocAry class created the two extra arrays needed to allow the previous and next entries to be easily found. The prev and next methods of that class then allow you to specify any key within the original array and return the appropriate previous or next key (or NULL if there isn't one) without having to rebuild the arrays each time you need to do a lookup.

class AssocAry {
private $keys, $keyIxs, $cnt;
function __construct($ary) {
$this->keys = array_keys($ary);
$this->keyIxs = array_flip($this->keys);
$this->cnt = count($ary)-1;
}
function prev($k) {
return ($this->keyIxs[$k] > 0) ? $this->keys[$this->keyIxs[$k]-1] : null;
}
function next($k) {
return ($this->keyIxs[$k] < $this->cnt) ? $this->keys[$this->keyIxs[$k]+1] : null;
}
}

You can add this functionality to any associative array by running the following statement where $myArray is your original associative array and $a is the object that will be created from it to provide the prev() and next() methods:

$a = new AssocAry($myArray);

You can then retrieve the key preceding a specific key in the array by calling $a->prev($aKey) or retrieve the key following a specific key by calling $a->next($aKey) where $aKey is any key in your original array.

 

This article written by Stephen Chapman, Felgall Pty Ltd.

go to top

FaceBook Follow
Twitter Follow
Donate