0

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.

Thanks for any suggestions.

Nick
  • 138,499
  • 22
  • 57
  • 95
zztop
  • 701
  • 1
  • 7
  • 20

1 Answers1

1

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

Nick
  • 138,499
  • 22
  • 57
  • 95
  • Possibly because of the older version of PHP, it is not accepting $results = []; $results = array(); seems to instantiate the empty array but then it is failing on $results[] = $obj; Is there another way to write that? – zztop Jun 10 '20 at 00:37
  • 1
    @zztop see my edit, I've updated that code. I forgot that the `[]` notation was so recent... – Nick Jun 10 '20 at 00:41
  • @Nick only if you consider [8 years ago](https://www.php.net/releases/index.php#5.4.0) to be _recent_ – Phil Jun 10 '20 at 01:05
  • 1
    @Phil that one should have triggered the sarcasm detector! :-) – Nick Jun 10 '20 at 01:06