8

I have an array within an array.

$array = [
    ['foo' => 'bar', 'value' => 'America'],
    ['value' => 'England', 'bar' => 'food'],
];

How do I check if 'America' exists in the array? The America array could be any key, and there could be any number of subarrays, so a generalized solution please.

Looking on the php manual, I see in_array(), but that only works for the top layer. so something like in_array("America", $a) would not work.

3
  • 1
    If all the arrays only contain one value why are you putting them into arrays? Why not just have the value assigned to that key? Commented Mar 12, 2010 at 21:13
  • Will the script be only looking for one or maybe a small amount of elements in a large multi-dimensional array? Or will it be searching for lots of elements which might make it "cheaper" to create a flat hashtable/array of all elements before searching? Commented Mar 12, 2010 at 21:16
  • Sorry, there was actually more values in the arrays, I tried to simplify it for the question, I guess that backfired. Commented Mar 12, 2010 at 21:19

5 Answers 5

14

A general solution would be:

function deep_in_array($needle, $haystack) {
    if(in_array($needle, $haystack)) {
        return true;
    }
    foreach($haystack as $element) {
        if(is_array($element) && deep_in_array($needle, $element))
            return true;
    }
    return false;
}

The reason why I chose to use in_array and a loop is: Before I examine deeper levels of the array structure, I make sure, that the searched value is not in the current level. This way, I hope the code to be faster than doing some kind of depth-first search method.


Of course if your array is always 2 dimensional and you only want to search in this kind of arrays, then this is faster:

function in_2d_array($needle, $haystack) {
    foreach($haystack as $element) {
        if(in_array($needle, $element))
            return true;
    }
    return false;
}
Sign up to request clarification or add additional context in comments.

7 Comments

I think the return after if(is_array...) is problematic. You cannot do a return for each element. Instead you should only return if call to deep_in_array returns true.
My array is always two dimensional. I love how both answers are named felix. :) Is your second option faster than the other felix's?
Hehe, actually I'm also "a Felix". The other Felix' answer is a general solution, not a two dimensional one.
@Mark: It depends on the structure of your array. Probably yes.
@middus: LOL, today is Felix day or what? ;) Btw my first code example is also general ;)
|
5

PHP doesn't have a native array_search_recursive() function, but you can define one:

function array_search_recursive($needle, $haystack) {
    foreach ($haystack as $value) {
        if (is_array($value) && array_search_recursive($needle, $value)) return true;
        else if ($value == $needle) return true;
    }
    return false;
}

Untested but you get the idea.

1 Comment

Hey Felix ;) Could be faster than mine because you traverse the array only once. On the other side you will always examine the arrays first although the search value might already exists in the current array level.
2
in_array("America", array_column($a, 'value'))

Comments

0
function search($a,$searchval){  //$a - array; $searchval - search value;
if(is_array($a)) {
foreach($a as $val){ 
if(is_array($val))
if(in_array($searchval,$val)) return true;  
}
}
else return false;
}

search($a, 'America'); //function call

Comments

0

Using PHP8.4 or a polyfill, you can enjoy a fully functional-style snippet and the performance boost of short-circuiting without needing to manually write a conditionally break. Demo

$find = 'America';
var_export(
    array_any(
        $array,
        fn($row) => in_array($find, $row)
    )
);
// true

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.