Filter arrays of data by any field in the array/objects
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;
}
}
Updated documentation and Coda Syntax mode to WordPress 3.3 “Sonny”
The latest and greatest WordPress 3.3, codename “Sonny” is ready for download.
Apart of all the little tweaks and fixes there are also a bunch of very useful feature coming along with this version:
Experienced users will appreciate the new drag-and-drop uploader, hover menus for the navigation, the new toolbar, improved co-editing support, and the new Tumblr importer. We’ve also been thinking a ton about what the WordPress experience is like for people completely new to the software. Version 3.3 has significant improvements there with pointer tips for new features included in each update, a friendly welcome message for first-time users, and revamped help tabs throughout the interface. Finally we’ve improved the dashboard experience on the iPad and other tablets with better touch support.
There is a ton of candy for developers as well. I’d recommend starting your exploration with the new editor API, new jQuery version, better ways to hook into the help screens, more performant post-slug-only permalinks, and of course the entire list of improvements on the Codex and in Trac.
Of course we updated our documentation to the newest version and also the WordPress Syntax Mode for Coda got an update.
Please have a look at our Function, Action and Filter index for a quick overview and see the list of some of the new and deprecated functions below.
New functions:
Theme related
- _wp_footer_scripts – Private, for use in *_footer_scripts hooks
- check_theme_switched – Checks if a theme has been changed and runs ‘after_switch_theme’ hook on the next WP load
- print_late_styles – Prints the styles that were queued too late for the HTML head.
Meta data related
- delete_metadata_by_mid – Delete meta data by meta ID
- delete_post_thumbnail – Removes a post thumbnail.
- get_metadata_by_mid – Get meta data by meta ID
- metadata_exists – Determine if a meta key is set for a given object
- register_meta – Register meta key
- update_metadata_by_mid – Update meta data by meta ID
Admin bar related
- wp_admin_bar_add_secondary_groups – Add secondary menus.
- wp_admin_bar_my_account_item – Add the "My Account" item.
- wp_admin_bar_search_menu – Add search form.
- wp_admin_bar_site_menu – Add the "Site Name" menu.
- wp_admin_bar_wp_menu – Add the WordPress logo menu.
Other functions
- is_main_query – Is the query the main query?
- wp_cache_decr – Decrement numeric cache item’s value
- wp_cache_incr – Increment numeric cache item’s value
- wp_editor – Renders an editor.
- wp_no_robots – Display a noindex meta tag.
- wp_trim_words – Trims text to a certain number of words.
Deprecated functions:
- _wp_admin_html_begin
- _ipad_meta
- wp_tiny_mce
- wp_quicktags
- wp_print_editor_js
- wp_preload_dialogs
- wp_admin_bar_dashboard_view_site_menu
- wpmu_admin_redirect_add_updated_param
- wpmu_admin_do_redirect
- type_url_form_video
- type_url_form_image
- type_url_form_file
- type_url_form_audio
- the_editor
- start_post_rel_link
- screen_options
- screen_meta
- screen_layout
- sanitize_user_object
- parent_post_rel_link
- media_upload_video
- media_upload_image
- media_upload_file
- media_upload_audio
- is_blog_user
- index_rel_link
- get_user_metavalues
- get_user_by_email
- get_userdatabylogin
- get_parent_post_rel_link
- get_index_rel_link
- get_boundary_post_rel_link
- favorite_actions
- add_contextual_help

April 13, 2012 

