PHP 将函数从循环更改为递归

PHP change a function from from loops to recursion

我有以下 JSON 对象:

{
    "id": 1,
    "name": null,
    "block": {
        "type": "none",
        "descends": [
            {
                "operation":"sum",
                "descends":[
                    {
                        "label":2,
                        "value":false
                    }
                ]
            },
            {
                "label": 1,
                "value": 3,
            },
            {
                "label": 2,
                "value": 2
            }
        ],
        "label": 1,
        "value": true
    }
}

我想收集所有 labelvalue 属性并将它们存储在一个数组中,所以我创建了以下函数:

public function collectValues($arr){
    $finalValues = [];
    foreach($arr as $key => $element){
        if($key=='block'){
            foreach($element as $key2 => $block){
                if($key2=='descends'){
                    foreach($block as $key3 => $node_block){
                        if($key3=='descends'){
                            foreach($node_block as $key4 => $anotherNode){
                                
                                if($key4 == 'descends'){
                                    foreach($anotherNode as $finalNode){
                                        $finalValues [] = array('lable'=>$finalNode->label, 'value' =>$finalNode->value);
                                    }

                                }
                            }
                            
                        }
                        else{
                            $finalValues [] = array('lable' => $node_block->label, 'value' => $node_block->value);
                        }
                    }
                }
            }

            $finalValues [] = array('lable'=> $element->label, 'value' => $element->value);
        }
    }

    return $finalValues;
}

函数有效,我得到以下信息:

[
    {
        "lable": 2,
        "value": false
    },
    {
        "lable": 1,
        "value": 3
    },
    {
        "lable": 2,
        "value": 2
    },
    {
        "lable": 1,
        "value": true
    }
]

问题是 JSON 对象可以包含更多 descends,例如:

{
    "id": 1,
    "name": null,
    "block": {
        "type": "none",
        "descends": [
            {
                "operation":"sum",
                "descends":[
                    {
                        "operation":"sum",
                        "descends":[
                            {
                                "label":2,
                                "value":false
                            }
                        ],
                        "label":2,
                        "value":false
                    }
                ]
            },
            {
                "operation":"sum",
                "descends":[
                    {
                        "label":2,
                        "value":false
                    }
                ],
                "label": 1,
                "value": 3,
            },
            {
                "label": 2,
                "value": 2
            }
        ],
        "label": 1,
        "value": true
    }
}

这意味着我将不得不添加更多的 foreach 循环。处理这种情况的一个好方法是使用递归。如何将上述函数转换为递归函数?

你的循环函数没有意义去改变。更容易从头开始重写 这是我的递归用例。也许有更简单的选择,但我没有追求优化

$array = json_decode($json, true); //in $json your JSON)
$result = []; // array for result
checkLabel($array, $result);
print_r($result);

function checkLabel(array $array, &$result){ 
    //first check every element on nested array
    foreach ($array as $key => $value){

        if (is_array($value)) {
            //if found call recursive function
            checkLabel($value, $result);
        }
    }
    //then check 'label' key.. its mean we have attribute
    if (array_key_exists('label', $array)) {
        //save it
        $result[] = [
            'label' => $array['label'],
            'value' => $array['value']??'' //if have label but without value)
        ];
    }
}