I frequently need to grab a subset of data from an array. I just stumbled over the FilterIterator which provides a nice interface to do just this. Based on this class here is a implementation which lets you perform basic filtering.
Here is an example:
$dummy_array = array(
array( 'id' => 1, 'name' => 'Jon Doe', 'date' => '2012-01-01' ),
array( 'id' => 2, 'name' => 'Jack Black', 'date' => '2012-02-01' ),
array( 'id' => 3, 'name' => 'Jane Doe', 'date' => '2012-02-04' ),
array( 'id' => 4, 'name' => 'Simon Smith', 'date' => '2012-03-01' ),
);
echo "\nall Doe\n";
$does = simple_array_filter( $dummy_array, 'name', 'regex', '#doe$#i' );
foreach( $does as $row )
var_export( $row );
echo "\nall in February\n";
$febs = simple_array_filter( $dummy_array )
->add_filter( 'date', 'newer_than', '2012-02-01 00:00:00' )
->add_filter( 'date', 'older_than', '2012-02-29 23:59:59' );
foreach( $febs as $row )
var_export( $row );
And here is the class that makes it happen.
/**
* Provide easy filtering iterator for arrays
* @see: http://php.net/manual/en/class.filteriterator.php
*/
class Simple_Array_Filter extends FilterIterator {
private $filters = array();
private $data = array();
public function __construct( $data, $filter_field = NULL, $filter_method = NULL, $filter_value = NULL ) {
$this->data = $data;
$iterator = $this->get_iterator();
parent::__construct( $iterator );
if ( ! is_null( $filter_field ) && ! is_null( $filter_method ) && ! is_null( $filter_value ) )
$this->add_filter( $filter_field, $filter_method, $filter_value );
}
public function get_iterator() {
if ( is_object( $this->data ) && method_exists( $this->data, 'getIterator' ) )
return $this->data->getIterator();
if ( is_array( $this->data ) ) {
$object = new ArrayObject( $this->data );
return $object->getIterator();
}
return $this->data;
}
public function accept() {
$data = $this->getInnerIterator()->current();
return $this->dispatch_filter( $data );
}
public function add_filter( $filter_field, $filter_method, $filter_value ) {
$this->filters[] = array( 'filter_field' => $filter_field, 'filter_method' => $filter_method, 'filter_value' => $filter_value );
return $this;
}
private function dispatch_filter( $data ) {
$result = true; // by default don't filter
foreach( $this->filters as $filter ) {
extract( $filter );
if ( is_object( $data ) ) {
if ( isset( $data->{$filter_field} ) ) {
$cmp_value = $data->{$filter_field};
}
} else if ( is_array( $data ) ) {
if ( isset( $data[$filter_field] ) ) {
$cmp_value = $data[$filter_field];
}
}
if ( empty( $cmp_value ) )
continue;
if ( is_callable( array( &$this, $filter_method ) ) )
$result = call_user_func( array( &$this, $filter_method ), $cmp_value, $filter_value );
else if ( function_exists( $filter_method ) ) {
$result = call_user_func( $filter_method, $cmp_value, $filter_value );
}
if ( false == $result )
return false;
}
return true;
}
private function gt( $cmp_value, $filter_value ) {
if ( is_numeric( $cmp_value ) )
return (int) $cmp_value > (int) $filter_value;
else
return strcmp( $cmp_value, $filter_value ) > 0;
}
private function lt( $cmp_value, $filter_value ) {
if ( is_numeric( $cmp_value ) )
return (int) $cmp_value < (int) $filter_value;
else
return strcmp( $cmp_value, $filter_value ) < 0;
}
private function eq( $cmp_value, $filter_value ) {
if ( is_numeric( $cmp_value ) )
return (int) $cmp_value == (int) $filter_value;
else
return strcmp( $cmp_value, $filter_value ) == 0;
}
private function regex( $cmp_value, $filter_value ) {
return preg_match( $filter_value, $cmp_value );
}
private function older_than( $cmp_value, $filter_value ) {
if ( !is_numeric( $cmp_value ) )
$cmp_value = strtotime( $cmp_value );
if ( !is_numeric( $filter_value ) )
$filter_value = strtotime( $filter_value );
else
$filter_value = $filter_value;
return $cmp_value < $filter_value;
}
private function newer_than( $cmp_value, $filter_value ) {
if ( !is_numeric( $cmp_value ) )
$cmp_value = strtotime( $cmp_value );
if ( !is_numeric( $filter_value ) )
$filter_value = strtotime( $filter_value );
else
$filter_value = $filter_value;
return $cmp_value > $filter_value;
}
}
if ( !function_exists( 'simple_array_filter' ) ) {
function simple_array_filter( $data, $filter_field = NULL, $filter_method = NULL, $filter_value = NULL ) {
$simple_array_filter = new Simple_Array_Filter( $data, $filter_field, $filter_method, $filter_value );
return $simple_array_filter;
}
}
42.671450
23.313666