<?php

function wp_list_filter_old( $list, $args = array(), $operator = 'AND' ) {
	if ( ! is_array( $list ) )
		return array();

	if ( empty( $args ) )
		return $list;

	$operator = strtoupper( $operator );
	$count = count( $args );
	$filtered = array();

	foreach ( $list as $key => $obj ) {
		$matched = count( array_intersect_assoc( (array) $obj, $args ) );
		if ( ( 'AND' == $operator && $matched == $count )
		  || ( 'OR' == $operator && $matched <= $count )
		  || ( 'NOT' == $operator && 0 == $matched ) ) {
			$filtered[$key] = $obj;
		}
	}

	return $filtered;
}

function wp_list_filter_new( $list, $args = array(), $operator = 'AND' ) {
	if ( ! is_array( $list ) )
		return array();

	if ( empty( $args ) )
		return $list;

	$operator = strtoupper( $operator );
	$count = count( $args );
	$filtered = array();

	foreach ( $list as $key => $obj ) {
		$to_match = (array) $obj;

		$matched = 0;
		foreach ( $args as $m_key => $m_value ) {
			if ( $m_value == $to_match[$m_key] )
				$matched++;
		}

		if ( ( 'AND' == $operator && $matched == $count )
		  || ( 'OR' == $operator && $matched <= $count )
		  || ( 'NOT' == $operator && 0 == $matched ) ) {
			$filtered[$key] = $obj;
		}
	}

	return $filtered;
}

function wp_list_filter_new2( $list, $args = array(), $operator = 'AND' ) {
	if ( ! is_array( $list ) )
		return array();

	if ( empty( $args ) )
		return $list;

	$operator = strtoupper( $operator );
	$count = count( $args );
	$filtered = array();

	foreach ( $list as $key => $to_match ) {
		if ( is_object( $to_match ) )
			$to_match = get_object_vars( $to_match );

		$matched = 0;
		foreach ( $args as $m_key => $m_value ) {
			if ( $m_value == $to_match[$m_key] )
				$matched++;
		}

		if ( ( 'AND' == $operator && $matched == $count )
		  || ( 'OR' == $operator && $matched <= $count )
		  || ( 'NOT' == $operator && 0 == $matched ) ) {
			$filtered[$key] = $obj;
		}
	}

	return $filtered;
}

function run_test( $callback, $args, $times ) {
	$start = microtime(true);

	for ( $i = 0; $i < $times; $i++ )
		call_user_func_array( $callback, $args );

	$stop = microtime(true);

	echo "$callback: " . ($stop - $start) . "\n";
}


$list = array();
foreach ( range( 1, 200 ) as $i ) {
	$list[] = (object) array(
		'foo' => rand(-100, 100),
		'bar' => rand(-100, 100),
		'baz' => rand(-100, 100),
		'bam' => rand(-100, 100),
	);
}

$args = array( $list, array( 'foo' => 100, 'baz' => '50', 'bam' => 0 ), 'AND' );

$times = 2000;

echo '<pre>';

run_test( 'wp_list_filter_old', $args, $times );

run_test( 'wp_list_filter_new', $args, $times );

run_test( 'wp_list_filter_new2', $args, $times );
