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; } }
No comments yet... Be the first to leave a reply!