This is my favorite algorithm for quickly finding what I need in a very large array, quickly. This is an implementation of the binary search algorithm that I have created and widely use in my PHP code. It easily handles iterative search procedures. You can change it in many ways to suit your needs, but the basic algorithm remains the same.
To use it (this option), the array must be sorted by the index you want to find in descending order.
function quick_find(&$array, $property, $value_to_find, &$first_index) { $l = 0; $r = count($array) - 1; $m = 0; while ($l <= $r) { $m = floor(($l + $r) / 2); if ($array[$m]->{$property} < $value_to_find) { $l = $m + 1; } else if ($array[$m]->{$property} > $value_to_find) { $r = $m - 1; } else { $first_index = $m; return $array[$m]; } } return FALSE; }
And to check this out:
class test_object { public $index; public $whatever_you_want; public function __construct( $index_to_assign ) { $this->index = $index_to_assign; $this->whatever_you_want = rand(1, 10000000); } } $my_array = array(); $my_index = rand(1256, 30000); $index_to_locate = $my_index + rand(200, 30234); for ($i = 0; $i < 1000000; $i++) { $searchable_object = new test_object($my_index);
Now a few notes:
You CAN use this to find non-unique indexes; the array MUST still be sorted in ascending order. Then, when it finds an element that matches your criteria, you must go back through the array to find the first element, or move forward to find the last one. This will add a few “hops” to your search, but most likely it will still be faster than iterating a large array.
For STRING indices, you can change arithmetic comparisons (that is, ">" and "<") in quick_find () to the PHP function "strcasecmp ()". Just make sure that the STRING indices are sorted the same way (for an example implementation): alphabetically and ascending.
And if you want to have a version that can search in arrays of objects sorted in ORDER in ascending or descending order:
function quick_find_a(&$array, $property, $value_to_find, &$first_index) { $l = 0; $r = count($array) - 1; $m = 0; while ($l <= $r) { $m = floor(($l + $r) / 2); if ($array[$m]->{$property} < $value_to_find) { $l = $m + 1; } else if ($array[$m]->{$property} > $value_to_find) { $r = $m - 1; } else { $first_index = $m; return $array[$m]; } } return FALSE; } function quick_find_d(&$array, $property, $value_to_find, &$first_index) { $l = 0; $r = count($array) - 1; $m = 0; while ($l <= $r) { $m = floor(($l + $r) / 2); if ($value_to_find > $array[$m]->{$property}) { $r = $m - 1; } else if ($value_to_find < $array[$m]->{$property}) { $l = $m + 1; } else { $first_index = $m; return $array[$m]; } } return FALSE; } function quick_find(&$array, $property, $value_to_find, &$first_index) { if ($array[0]->{$property} < $array[count($array)-1]->{$property}) { return quick_find_a($array, $property, $value_to_find, $first_index); } else { return quick_find_d($array, $property, $value_to_find, $first_index); } }