Как использовать рекурсию для суммирования определенных значений в многомерном массиве? - PullRequest
0 голосов
/ 10 ноября 2018

У меня есть данные многоуровневого объекта со структурой, аналогичной окну ниже.

Я пытаюсь

  • Суммируйте все прямые значения пакета для лучших пользователей или произнесите parents, только
  • суммирует все значения вложенных косвенных пакетов из дерева children.

Ожидается, что окончательный результат будет похож на: [{"sum_direct": 600},{"sum_indirect": 3000}]

Мне нужна помощь, чтобы узнать, что я делаю неправильно:

function sumDirect($c) {
    if(count($c) > 0){
        $sum = 0;
        foreach ($c as $package) {
            $sum += $package['package']['direct'];
        }
    } else {
        $sum = 0;
    }
    return $sum;
}

function sumIndirect($c) {
    if(count($c) > 0){
        $sum = 0;
        foreach ($c as $package) {
            if(count($package['children']) > 0) {
                foreach ($package['children'] as $children){
                    $sum += $children['indirect'];
                    $sum += sumIndirect($children);
                }
            }
        }
    } else {
        $sum = 0;
    }
    return $sum;
}

Пример ввода:

{
  "users": [{
      "user_id": 2,
      "ref_id": 1,
      "package": [{
          "name": "Basic"
        },
        {
          "direct": 200
        },
        {
          "indirect": 100
        }
      ],
      "children": [{
          "user_id": 58,
          "ref_id": 2,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 59,
          "ref_id": 2,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 111,
          "ref_id": 2,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 116,
          "ref_id": 2,
          "package": [{
              "name": "Diamond"
            },
            {
              "direct": 1000
            },
            {
              "indirect": 500
            }
          ],
          "children": 0
        },
        {
          "user_id": 119,
          "ref_id": 2,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        }
      ]
    },
    {
      "user_id": 100,
      "ref_id": 1,
      "package": [{
          "name": "Basic"
        },
        {
          "direct": 200
        },
        {
          "indirect": 100
        }
      ],
      "children": [{
          "user_id": 101,
          "ref_id": 100,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 102,
          "ref_id": 100,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 103,
          "ref_id": 100,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 104,
          "ref_id": 100,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 105,
          "ref_id": 100,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 106,
          "ref_id": 100,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 107,
          "ref_id": 100,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 108,
          "ref_id": 100,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 109,
          "ref_id": 100,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 110,
          "ref_id": 100,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        },
        {
          "user_id": 117,
          "ref_id": 100,
          "package": [{
              "name": "Diamond"
            },
            {
              "direct": 1000
            },
            {
              "indirect": 500
            }
          ],
          "children": 0
        },
        {
          "user_id": 129,
          "ref_id": 100,
          "package": [{
              "name": "Diamond"
            },
            {
              "direct": 1000
            },
            {
              "indirect": 500
            }
          ],
          "children": 0
        },
        {
          "user_id": 130,
          "ref_id": 100,
          "package": [{
              "name": "Basic"
            },
            {
              "direct": 200
            },
            {
              "indirect": 100
            }
          ],
          "children": 0
        }
      ]
    }
  ]
}

Полные данные на users.json

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Рекурсия не кажется необходимой для "родительских" прямых значений, так что это можно сделать с помощью прямого цикла foreach.

"Дети" косвенные значения требуют рекурсии. Я решил использовать array_walk_recursive() для доступа к каждому «листовому узлу» в массиве. Это также будет хранить косвенные значения родителей, поэтому я вычитаю эти значения после завершения array_walk_recursive().

Код: ( Демо )

$result['sum_direct'] = 0;
$result['sum_indirect'] = 0;
$parents_indirect = 0;
echo "<pre>";
$array = json_decode($json, true)['users'];
foreach ($array as $users) {
    $result['sum_direct'] += $users['package'][1]['direct'];
    $parents_indirect += $users['package'][2]['indirect'];
}
array_walk_recursive($array, function ($v, $k) use (&$result) {
        if ($k === 'indirect') {
            $result['sum_indirect'] += $v;
        }
    });
$result['sum_indirect'] -= $parents_indirect;

echo json_encode($result);

Вывод с использованием ваших данных:

{"sum_direct":400,"sum_indirect":3000}

Вывод с использованием вашего полного json из github:

{"sum_direct":600,"sum_indirect":22400}
0 голосов
/ 10 ноября 2018

простой способ может быть основан на паре для каждого вложенного другого

$result['sum_direct'] = 0;
$result['sum_indirect'] = 0;

$myArray = json_decode($myJsonString, TRUE)
  foreach($myArray['users'] as  $value){
  $result['sum_direct'] += $value['package']['direct'];
  foreach($value['children']['package'] as  $value2){
    $result['sum_indirect']  += $value2['indirect'];
  }
}

$jsonResult= json_encode($result);
...