I Am Stack
I Am Stack

Reputation: 241

php array search from multidimensional array by single or multiple word

I've a multidimensional array. I want to search in array using single or double word inside it and return the array's that contain any matched word...

Here is my example array:

$array = array(
            array('First_name' => 'Dina', 'Last_Name' => 'Gomez', 'Location' => 'Los Angeles, CA', 'Work' => 'Youtube Service')
            array('First_name' => 'Lopa', 'Last_Name' => 'Mitchel', 'Location' => 'New York, NY', 'Work' => 'Works with Mark')
            array('First_name' => 'Mark ', 'Last_Name' => 'Nailson Jr.', 'Location' => 'Dallas, USA', 'Work' => 'SEO Industry')
            array('First_name' => 'Jenna', 'Last_Name' => 'Gomez', 'Location' => 'Florida, CA', 'Work' => 'Work at Youtube')
            );

Now If someone search "Gomez" then it should return 1st and last array..I can do it using in_array() but problem is this, I in_array() only return exact match. I want partial match content too.. like if someone search "Mark Gomez" then it should return 1st array, last array for "Gomez" and 2nd & third array for "Mark" .. 2nd array has "Mark" word at Work Key.

I collect a function from another stackoverflow answer.. which is only work for exact match.. or for some key's only..

function checkarrayvalues($term, $arr, $strict = false, $partial = false) {
        if ($partial) {  // whether it should perform a partial match
            $fn = ($strict) ? "strpos" : "stripos";
        }
        foreach ($arr as $item) {
            if (is_array($item)) {
                if (checkarrayvalues($term, $item, $strict, $partial))
                    return true;
            } elseif (($partial && call_user_func($fn, $item, $term) !== false) 
                    || ($strict ? $item === $term : $item == $term)) {
                return true;
            }
        }
        return false;
    }

    var_dump(checkarrayvalues($query, $results, false, true));

I also tried array_search function :( No luck.

Please help :(

Upvotes: 1

Views: 357

Answers (1)

Syscall
Syscall

Reputation: 19779

You were very close. You can explode the input terms and search them separately to find occurrences in the array. Then, you cannot return directly the value of the recursive array, because you'll break the loop. You can use a variable and return it at the end of the loop

Here is a demo.

The function :

function checkarrayvalues(&$out, $terms, $input, $strict = false, $partial = false) {

    if ($partial) {  // whether it should perform a partial match
        $fn = ($strict) ? "strpos" : "stripos";
    }

    $found = false ;
    foreach ($input as $key => $item) {
        if (is_array($item)) {
            if (checkarrayvalues($out, $terms, $item, $strict, $partial)) {
                $found = true;
            }
        }
        else {
            foreach ($terms as $term) {
                if (($partial && call_user_func($fn, $item, $term) !== false)
                    || ($strict ? $item === $term : $item == $term))
                {
                    $out[] = ['item' => $item, 'key' => $key] ;
                    $found = true;
                }
            }
        }
    }
    return $found;
}

Usage:

$array = [
    ['First_name' => 'Dina', 'Last_Name' => 'Gomez', 'Location' => 'Los Angeles, CA', 'Work' => 'Youtube Service'],
    ['First_name' => 'Lopa', 'Last_Name' => 'Mitchel', 'Location' => 'New York, NY', 'Work' => 'Works with Mark'],
    ['First_name' => 'Mark', 'Last_Name' => 'Nailson Jr.', 'Location' => 'Dallas, USA', 'Work' => 'SEO Industry'],
    ['First_name' => 'Jenna', 'Last_Name' => 'Gomez', 'Location' => 'Florida, CA', 'Work' => 'Work at Youtube'],
];


$out = [];
if (checkarrayvalues($out, ["New York"], $array, false, false)) {
    print_r($out);
}
$out = [];
if (checkarrayvalues($out, ["Mark","Gomez"], $array, false, false)) {
    print_r($out);
}
$out = [];
if (checkarrayvalues($out, ["Mark"], $array, false, true)) {
    print_r($out);
}

Outputs:

Array ( [0] => Array ( [item] => New York, NY [key] => Location ) ) 
Array ( [0] => Array ( [item] => Gomez [key] => Last_Name ) [1] => Array ( [item] => Mark [key] => First_name ) [2] => Array ( [item] => Gomez [key] => Last_Name ) ) 
Array ( [0] => Array ( [item] => Works with Mark [key] => Work ) [1] => Array ( [item] => Mark [key] => First_name ) )

Of course, instead of storing the item, you could store the $input, or the index.

Upvotes: 1

Related Questions