Check arrays for recursion

前端 未结 5 1073
误落风尘
误落风尘 2021-02-05 22:29

What is the best way to check if an array is recursive in PHP ?

Given the following code:



        
5条回答
  •  一个人的身影
    2021-02-05 23:16

    It's always fun to try solving "impossible" problems!

    Here's a function that will detect recursive arrays if the recursion happens at the top level:

    function is_recursive(array &$array) {
        static $uniqueObject;
        if (!$uniqueObject) {
            $uniqueObject = new stdClass;
        }
    
        foreach ($array as &$item) {
            if (!is_array($item)) {
                continue;
            }
    
            $item[] = $uniqueObject;
            $isRecursive = end($array) === $uniqueObject;
            array_pop($item);
            if ($isRecursive) {
                return true;
            }
        }
    
        return false;
    }
    

    See it in action.

    Detecting recursion at any level would obviously be more tricky, but I think we can agree that it seems doable.

    Update

    And here is the recursive (pun not intended but enjoyable nonetheless) solution that detects recursion at any level:

    function is_recursive(array &$array, array &$alreadySeen = array()) {
        static $uniqueObject;
        if (!$uniqueObject) {
            $uniqueObject = new stdClass;
        }
    
        $alreadySeen[] = &$array;
    
        foreach ($array as &$item) {
            if (!is_array($item)) {
                continue;
            }
    
            $item[] = $uniqueObject;
            $recursionDetected = false;
            foreach ($alreadySeen as $candidate) {
                if (end($candidate) === $uniqueObject) {
                    $recursionDetected = true;
                    break;
                }
            }
    
            array_pop($item);
    
            if ($recursionDetected || is_recursive($item, $alreadySeen)) {
                return true;
            }
        }
    
        return false;
    }
    

    See it in action.

    Of course this can also be written to work with iteration instead of recursion by keeping a stack manually, which would help in cases where a very large recursion level is a problem.

提交回复
热议问题