1

I try to find a value in an array, no matter how deep that array is or what "structure" it may have. But my approach doesn't find all values. I think I get the recursion wrong, but I don't know.

$haystack = array(
        'A',
        'B' => array('BA'),
        'C' => array('CA' => array('CAA')),
        'D' => array('DA' => array('DAA' => array('DAAA')))
    );

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

$find = array('A', 'BA', 'CAA', 'DAAA');

foreach($find as $needle) {
    if (array_find($needle, $haystack)) {
        echo $needle, " found".PHP_EOL;
    } else {
        echo $needle, " not found".PHP_EOL;
    }
}
strudelkopf
  • 671
  • 1
  • 6
  • 12
  • 2
    Your search is certainly redundant. You have both `in_array` and `$value == $needle` to possibly hit the value. At least it's redundant, at worst it's a bug. – deceze Aug 21 '14 at 13:29

2 Answers2

7

Simply change your code to:

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

The problem is in your return statement.

micnic
  • 10,915
  • 5
  • 44
  • 55
1

I think this can be written more simply:

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

I do not know whether or not there is a benefit to using in_array rather than just making the recursive call as soon as you determine it is an array.

Don't Panic
  • 41,125
  • 10
  • 61
  • 80