Filter array elements by searching for partial match in keys and values

Viewed 4352

is it possible to do searching in PHP array same we do in MySQL.

Eg: I have this array

array(
  'mark@test.com'=> `Mark Mian`,
  'jhon@test.com'=> `John jack`,
  'logon@test.com'=> `Bob Logon`,
  'Stela@test.com'=> `Stela Josh`,
  'json@test.com'=> `Json Josh`
  'bobby@test.com'=> `Bob Mark`
)

and I would to do this type of searching,

Eg: If I search Mark it should return me this

'mark@test.com' => `Mark Mian

If I search Bob it should return me

'bobby@test.com'=> Bob Mark

'logon@test.com'=> Bob Logon,

If I search only a it should return me those elements which contains a eg:

'mark@test.com'=> Mark Mian,

'jhon@test.com'=> John jack,

'Stela@test.com'=> Stela Josh,

'bobby@test.com'=> Bob Mark

Note: Search should be by key or value

7 Answers
   $search = "Mark"

  $array = array(
  'mark@test.com'=> `Mark Mian`,
 'jhon@test.com'=> `John jack`,
 'logon@test.com'=> `Bob Logon`,
 'Stela@test.com'=> `Stela Josh`,
 'json@test.com'=> `Json Josh`
'bobby@test.com'=> `Bob Mark`
 )
       foreach ($array as $key => $value) {
         if (stristr($value, $search) == '') {
        //not found
        }else{
      //found
       }

this is the best approach search for any substring , case-insensitive and fast

just like like in mysql

ex:

select * from table where name = "%Mark%"

From PHP8, str_contain() becomes the preferred native function to make case-insensitive searches without reduced syntax.

Searching for a lowercase b does a fine job of demonstrating the case-insensitive search on keys and values.

Code: (Demo)

$array = [
    'mark@test.by.com'=> "Mark Mian lv",
    'jhon@test.lv.com'=> "John jack lv",
    'logon@test.en.com'=> "Bob Logon",
    'Stela@test.es.com'=> "Stela Josh",
    'json@test.es.com'=> "Json Josh",
    'bobby@test.lv.com'=> "Bob Mark"
];

$needle = 'b';

var_export(
    array_filter(
        $array,
        fn($v, $k) => str_contains($v, $needle) || str_contains($k, $needle),
        ARRAY_FILTER_USE_BOTH
    )
);

Output:

array (
  'mark@test.by.com' => 'Mark Mian lv',
  'logon@test.en.com' => 'Bob Logon',
  'bobby@test.lv.com' => 'Bob Mark',
)

If you want to be cute and make a single function call inside of array_filter(), then you could just concatenate $v and $k together, but then you risk the arbitrarily nominated delimiting character(s) being matched. For stability, just make two calls per iteration.

$data_array = array_filter($data_array , function ($item) use ($your_string) {
            return strpos($item['array_key'], $your_string) !== false;
        });

This replace the array with matching string

Related