从 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);
我有一个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);