开发者

filter values from an array similar to SQL LIKE '%search%' using PHP

开发者 https://www.devze.com 2023-02-28 22:41 出处:网络
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 al开发者_如何学JAVAphabetic matc

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 al开发者_如何学JAVAphabetic 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;
  }
}


like %search%

function like(array $arr, string $patron): array
    {
        return array_filter($arr, static function (mixed $value) use ($patron): bool {
            return 1 === preg_match(sprintf('/^%s$/i', preg_replace('/(^%)|(%$)/', '.*', $patron)), $value);
        });
    }

test

$b=['a'=>'peter','b'=>'patter','c'=>'alter','d'=>'all'];
var_dump(like($b,'%ter'));// ['a'=>'peter','b'=>'patter','c'=>'alter']
var_dump(like($b,'al%'));//['c'=>'alter','d'=>'all']
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号