filter values from an array similar to SQL LIKE '%search%' using PHP
I created an autocomplete field using JQueryUI and I've stored my data in a flat doc. I can read the values into an array... but I would like to be able to return the alphabetic matches based on the user input. So if the array contains [orange,blue,green,red,pink,brown,black]
and the user types bl then I only return [blue,black]
.
Looking at array_diff()
but without complete matches on the entire value of the array, I'm not sure how to use it... maybe a regular expression thrown in? My two weakest skills array manipulation and regex Thanks for the help!
You don't need to use array_filter
and a custom / lambda function, preg_grep
does the trick:
$input = preg_quote('bl', '~'); // don't forget to quote input string!
$data = array('orange', 'blue', 'green', 'red', 'pink', 'brown', 'black');
$result = preg_grep('~' . $input . '~', $data);
array_filter()
, with a callback filtering function based on stripos()
, should do the trick.
For example, if the input is stored in $input
, and your array in $data
:
$input = 'bl';
$data = array('orange', 'blue', 'green', 'red', 'pink', 'brown', 'black');
Filtering to keep only the words that contain $input
(no matter where in the string) could be done this way :
$result = array_filter($data, function ($item) use ($input) {
if (stripos($item, $input) !== false) {
return true;
}
return false;
});
var_dump($result);
And, here, you'd get :
array
1 => string 'blue' (length=4)
6 => string 'black' (length=5)
Changing the filtering callback, you can :
- Test if the string begins with the input -- testing if the value returned by
stripos()
is=== 0
- Use a case-sensitive matching function, like
strpos()
You could simply iterate through the array to look for all strings that start with the given letters. Having the list of words already sorted in your flat file would probably speed things up. I think this works pretty well:
$input = strtolower("bl"); //from the user
$colors = array("black", "blue", "brown", "..."); //already sorted alphabetically
$matches = array();
foreach ($colors as $c){
if (strpos($c, $input) === 0){
//if $c starts with $input, add to matches list
$matches[] = $c;
} else if (strcmp($input, $c) < 0){
//$input comes after $c in alpha order
//since $colors is sorted, we know that we won't find any more matches
break;
}
}