从 php 中 json 的子值之和更新父值

Update parent value from sum of children values of a json in php

我有一个json字符串

$json = '{
    "id": 1,
    "label": "Beef",
    "sector_page_id": null,
    "value": 0,
    "tree_children": [
        {
            "id": 46,
            "label": "Beef",
            "sector_page_id": null,
            "value": 0,
            "tree_children": [
                {
                    "id": 47,
                    "label": "Beef - UK",
                    "sector_page_id": null,
                    "value": 15,
                    "tree_children": []
                },
                {
                    "id": 48,
                    "label": "Beef - Europe",
                    "sector_page_id": null,
                    "value": 25,
                    "tree_children": []
                },
                {
                    "id": 49,
                    "label": "Beef - Rest of World",
                    "sector_page_id": null,
                    "value": 0,
                    "tree_children": []
                }
            ]
        }]
    }' ;

每个 tree_children 值的总和将根据父值进行更新,因此更新后的 json 将如下所示:

$json = '{
"id": 1,
"label": "Beef",
"sector_page_id": null,
"value": 40,
"tree_children": [
    {
        "id": 46,
        "label": "Beef",
        "sector_page_id": null,
        "value": 40,
        "tree_children": [
            {
                "id": 47,
                "label": "Beef - UK",
                "sector_page_id": null,
                "value": 15,
                "tree_children": []
            },
            {
                "id": 48,
                "label": "Beef - Europe",
                "sector_page_id": null,
                "value": 25,
                "tree_children": []
            },
            {
                "id": 49,
                "label": "Beef - Rest of World",
                "sector_page_id": null,
                "value": 0,
                "tree_children": []
            }
        ]
    }]
}' ;

说明:

我的进度不尽如人意,但仍想分享片段 Snippet Link

$obj =  json_decode($json, 1);


    
    array_walk_recursive($obj, function(&$item, $key) use($obj){
        $sum = 0;
        
        array_walk_recursive($obj, function($item1, $key1) use (&$sum){
            if($key1 == 'value'){
                $sum += $item1;
            }
        });

        if($key == 'value'){
            if($item == 0){
                $item = $sum;
            }
        }
    });
    
    print_r($obj);

你应该像下面这样使用递归函数。

$obj =  json_decode($json, 1);

// it is important to pass the obj by reference
function recursive_sum (&$obj) {
    if ( count($obj["tree_children"]) == 0 ) {
        return $obj["value"];
    }
    // don't forget to iterate the child using pass-by-reference &
    foreach ( $obj["tree_children"] as &$_obj )
        $obj["value"] += recursive_sum($_obj);
    return $obj["value"];
}
        
recursive_sum($obj);
print_r($obj);

我的工作片段

function recursive_sum (&$arr, $sum = 0){
   if(isset($arr['tree_children']) && !empty($arr['tree_children'])){
      foreach($arr['tree_children'] as &$eachChild){
        $sum += $eachChild['value'];
        $arr['value'] = recursive_sum ($eachChild, $sum);
      }
   }
   return $sum;
}

将您的 json 解码为对象非常适合此任务,因为默认情况下对象可通过引用进行修改。换句话说,您不需要在变量前显式地写 &

递归时不需要检查相关属性是否存在或为空,因为样本数据中访问的属性总是存在的。

在每个级别循环 tree_children 并将递归其子项的总和值添加到其 value

顶层 return 将提供总和,但初始函数调用不使用该值,因为 sum_recursive() 调用纯粹用于修改对象。

代码:(Demo)

$obj = json_decode($json);

function sum_recursive(object $obj): int {
    foreach ($obj->tree_children as $child) {
        $obj->value += sum_recursive($child);
    }
    return $obj->value;
}
   
sum_recursive($obj);
var_export($obj);