Skip to content

Instantly share code, notes, and snippets.

@lukemorton
Created March 10, 2011 13:38
Show Gist options
  • Save lukemorton/864096 to your computer and use it in GitHub Desktop.
Save lukemorton/864096 to your computer and use it in GitHub Desktop.
Array sorting class
<?php
/**
* ArrayPlay.
*
* An handy class for sorting arrays, more features as required.
*
* @author Luke Morton
* @example
* $original = array(
* array('name' => 'James', 'age' => 25),
* array('name' => 'Bob', 'age' => 44),
* array('name' => 'Kenny', 'age' => 32),
* array('name' => 'Thomas', 'age' => 19),
* );
*
* var_dump($original);
*
* $arr = new ArrayPlay($original);
*
* $sorted = $arr
* ->sort_by_key_value('name', 'desc')
* ->sort_by_key_value('age', 'asc')
* ->get_processed();
*
* var_dump($sorted);
*
* @example
* $array_a = array(
* array('name' => 'James', 'age' => 25, 'status' => 'cool'),
* array('name' => 'Bob', 'age' => 44, 'status' => 'boring'),
* array('name' => 'Kenny', 'age' => 32, 'status' => 'clever'),
* array('name' => 'Thomas', 'age' => 19, 'status' => 'cool'),
* );
*
* $array_b = array(
* array('name' => 'Zeb', 'age' => 25, 'status' => 'clever'),
* array('name' => 'Cain', 'age' => 28, 'status' => 'tidy'),
* array('name' => 'Paul', 'age' => 41, 'status' => 'boring'),
* array('name' => 'Luke', 'age' => 32, 'status' => 'boring'),
* array('name' => 'David', 'age' => 79, 'status' => 'cool'),
* );
*
* var_dump($array_a, $array_b);
*
* $arr = ArrayPlay::factory()
* ->filter_by_key_value('status', array('cool', 'clever', 'boring'))
* ->sort_by_key_value('name', 'desc')
* ->sort_by_key_value('age', 'asc');
*
* $array_a = $arr->get_processed($array_a);
* $array_b = $arr->get_processed($array_b);
*
* var_dump($array_a, $array_b);
*
*/
class ArrayPlay {
/**
* Factory method for ArrayPlay.
*
* @param array Array to play with (optional)
* @return void
*/
public function factory($array = NULL)
{
return new ArrayPlay($array);
}
/**
* @var array Original Array
* @protected
*/
protected $_original = NULL;
/**
* @var array Manipulated Array
* @protected
*/
protected $_array = NULL;
/**
* @var array Sorting/filtering queue
* @protected
*/
protected $_queue = array();
/**
* Create new array play.
*
* @param array Array to play with (optional)
* @return void
*/
public function __construct($array = NULL)
{
if (isset($array))
{
$this->set_array($array);
}
}
/**
* Add sort by key to sort queue.
*
* @param string Key name
* @param string Direction can be 'asc' or 'desc' (optional)
* @return $this
*/
public function sort_by_key_value($key, $direction = 'asc')
{
$this->_queue_add(array('sort_key_value', $key, $direction));
return $this;
}
/**
* Filter and order array by a key's value.
*
* @param string Key name to filter by
* @param array Array of values to order and filter
* @return $this
*/
public function filter_by_key_value($key, $key_order)
{
$this->_queue_add(array('filter_key_value', $key, $key_order);
return $this;
}
/**
* Process an array.
*
* @param array Optional array to sort
* @return $this
*/
public function process($array_to_sort = NULL)
{
if (isset($array_to_sort))
{
$this->set_array($array_to_sort);
}
$this->_queue_process();
return $this;
}
/**
* Clear sort queue.
*
* @return $this
*/
public function clear()
{
$this->_queue_clear();
return $this;
}
/**
* Get original array.
*
* @return array Original array
*/
public function get_original()
{
return $this->_original;
}
/**
* Get manipulated array.
*
* @return array Manipulated array
*/
public function get_array()
{
return $this->_array;
}
/**
* Get sorted array.
*
* This method basically runs all pending sort instructions
* then returns the sorted array.
*
* @param array Optional array to sort
* @return array Sorted array
*/
public function get_processed($array_to_sort = NULL)
{
return $this->process($array_to_sort)->_array;
}
/**
* Set a new array to object, this updates $this->_original.
*
* @param array New array
* @param bool Clear sort queue (optional)
* @return $this
*/
public function set_array($array, $clear = FALSE)
{
$this->_array =
$this->_original = $array;
if ($clear === TRUE)
{
$this->_queue_clear();
}
return $this;
}
/**
* Add new sort to sort queue.
*
* @param array $type, $value, $direction
* @return void
* @protected
*/
protected function _queue_add($sort)
{
$this->_queue[] = $sort;
}
/**
* Process sort queue on current array.
*
* @return void
* @protected
*/
protected function _queue_process()
{
$key_sort =
$key_sort_dir = array();
foreach (array_reverse($this->_queue) as $_queue)
{
// We will not bother listing but this is what
// each array value should represent:
// list($sort_type, $sort_val, $sort_direction) = $_sort;
if ($_queue[0] === 'sort_key_value')
{
foreach ($this->_array as $_k => $_v)
{
$key_sort[$_queue[1]][$_k] = $_v[$_queue[1]];
$key_sort_dir[$_queue[1]] = $_queue[2] === 'asc' ? SORT_ASC : SORT_DESC;
}
array_multisort($key_sort[$_queue[1]], $key_sort_dir[$_queue[1]], $this->_array);
}
else if ($_queue[0] === 'filter_key_value')
{
$filtered_array = array();
foreach($_queue[2] as $_key_value)
{
foreach ($this->_array as $_k => $_v)
{
if ($_v[$_queue[1]] === $_key_value)
{
$new_array[$_k] = $_v;
}
}
}
$this->_array = $filtered_array;
}
}
}
/**
* Clear sort queue.
*
* @return void
* @protected
*/
protected function _queue_clear()
{
$this->_queue = array();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment