phpmultidimensional-arrayfilteringcase-insensitive

Case-insensitively filtering a 2d array by value in any column


I would like to filter (search) a multidimensional array by a search term. I don't want strict identity of the search term to the keys or values but rather more like a case-insensitive contains.

The data in JSON looks like the following:

[
    {"title":"The Call of the Wild","author":"Jack London"},
    {"title":"Great Expectations","author":"Charles Dickens"},
    {"title":"The Voyage of the Beatle","author":"Charles Darwin"}
]

I would like to be able to be able to return an array of results based on the search. For example, a search on the word charles should pull up the second two titles whereas a search on wild should return the first title.

I've been trying to modify the following and answers here but it seems to just give me the index of the array. How can I search on the values for both the title and author of all the elements in the array?

function searchArrayKeyVal($sKey, $search, $array) {
    foreach ($array as $key => $val) {
        if (strpos(strtolower($val[$sKey]), strtolower(trim($search))) !== false) {
            return $key;
        }
    }
         return false;
 }

FYI, there is an older version of PHP (5.3) I can't change on my client's host so I can't use newer methods.


Solution

  • Assuming you have decoded your JSON to an array, you can use this function to search. It looks through each entry of the array, searching each of the values for the search string using stripos to do a case-insensitive search. Any matching entries are pushed to the $results array, which is returned at the end of the function:

    function searchArrayKeyVal($search, $array) {
        $results = array();
        // search for string in each column
        foreach ($array as $idx => $obj) {
            foreach ($obj as $key => $value) {
                if (stripos($value, $search) !== false) {
                    array_push($results, $obj);
                    break;
                }
            }
        }
        return $results;
    }
    
    print_r(searchArrayKeyVal('charles', $array));
    print_r(searchArrayKeyVal('wild', $array));
    

    Output:

    Array
    (
        [0] => Array
            (
                [title] => Great Expectations
                [author] => Charles Dickens
            )
        [1] => Array
            (
                [title] => The Voyage of the Beatle
                [author] => Charles Darwin
            )
    )
    
    Array
    (
        [0] => Array
            (
                [title] => The Call of the Wild
                [author] => Jack London
            )
    )
    

    Demo on 3v4l.org