每个级别的数组/层次结构的总分层数组

时间:2017-05-08 15:49:43

标签: php arrays sum array-sum

我有一个数组,其结构类似于下面的结构。哪里有heirarchy

[2] => Array
        (
            [sumW] => 200.39
            [child] => Array
                (
                    [3] => Array
                        (
                            [sumW] => 300.00
                        )
                    [4] => Array
                        (
                            [sumW] => 100.28
                            [child] => Array
                                (
                                    [5] => Array
                                        (
                                            [sumW] => 600
                                        )

                                    [6] => Array
                                        (
                                            [sumW] => 150
                                        )

                                 )
                         )

                    [7] => Array
                        (
                            [sumW] => 30.00
                            [child] => Array
                                (
                                    [8] => Array
                                        (
                                            [sumW] => 100.00
                                        )

                                 )
                         )

                 )
        )

```

我无法弄清楚如何在数组的每个级别对每个数组求和。因此,每个级别都有自己的总和以及低于它的水平。

所以,例如,像

[2]   = [tot] => 1480.67
 [3]  = [tot] => 300.00
 [4]  = [tot] => 850.28
  [5] = [tot] => 600.00
  [6] = [tot] => 150.00
 [7]  = [tot] => 130.00
  [8] = [tot] => 100.00

等等。

数组可以是无限级别,这只显示3个级别,但我的层次结构可能会延伸到3级以上。

我已尝试弄乱数组和并在数组中设置父/子ID。我能做的最好的是得到2-> 3,4,7的值。但我不能[2]将[5]和[6]以及之后的值包括在内。

编辑:

这是我尝试过的一种方法。我的原始数据中有parent_ids和category_ids。这使我的每个级别的总和达到1级。但是并没有对层次结构中的所有内容求和。

$tot=[];
$getSum = function ($array, $pid = null) use (&$getSum, &$tot) {
             $rpt = new Report;
             foreach ($array as $item) {
         // This returns my database value for this category.
                 $sum = $rpt->getCategoryTotal($item->category_id);

                 if($item->parent_id == $pid) {

                     if(!isset($tot[$item->category_id])){
                         $tot[$item->category_id] = $sum;
                     }   

                     if(isset($tot[$item->parent_id])){
                         $tot[$item->parent_id] += $sum;
                     }   

                     $child = $getSum($item->children, $item->category_id);
                 }
             }           
             return $sum;
         };

$result = $getSum($myDbData);
return dd($tot);

2 个答案:

答案 0 :(得分:0)

我找到了一个似乎对我有用的解决方案。 Haven没有对它进行彻底的测试,但到目前为止它似乎正在发挥作用。

     function setTotals($category) {
         $category['totalW'] = $category['sumW'];
         if (isset($category['child']) && is_array($category['child'])) {
             $sub = [];
             $i = 0;
             foreach ($category['child'] as $cat) {
                 $sub[] = setTotals($cat);
                 $category['totalW'] += $sub[$i]['totalW'];
                 $i++;
             }
             $category['child'] = $sub;
         }
         return $category;
     }   
     setTotals($myArray);

这适用于问题中发布的数组结构,并添加了一个' total'每个级别的行,以及该级别的总和,包括级别。

希望这有助于其他人。

信用:我在这里找到了帮助我完成这项工作。 codepad

答案 1 :(得分:0)

我认为这样的递归函数:

public function recursiveSum(array $source)
{
    $children = $source['child'] ?? [];

    $sum = $source['sumW'] ?? 0;

    foreach($children as $index => $child)
    {
        $source['child'][$index] = $this->recursiveSum($child);
        $sum += $source['child'][$index]['total'];
    }

    $source['total'] = $sum;
    return $source;
}

如果你需要一个上层的结果,这个将需要"孩子"键。

以下是我为测试而制作的数据的实现:

$datas = [
    'child' => [
        2 => [
            'sumW' => 200.39,
            'child' => [
                3 => [
                    'sumW' => 300,
                ],
                4 => [
                    'sumW' => 100.28,
                    'child' => [
                        5 => [
                            'sumW' => 600,
                        ],
                        6 => [
                            'sumW' => 150,
                        ],
                    ]
                ],
                7 => [
                    'sumW' => 30,
                    'child' => [
                        5 => [
                            'sumW' => 100,
                        ],
                    ],
                ],
            ],
        ],
    ]
];

输出:

array:2 [▼
    "child" => array:1 [▼
        2 => array:3 [▼
            "sumW" => 200.39
            "child" => array:3 [▼
                3 => array:2 [▼
                    "sumW" => 300
                    "total" => 300
                ]
                4 => array:3 [▼
                    "sumW" => 100.28
                    "child" => array:2 [▼
                        5 => array:2 [▼
                            "sumW" => 600
                            "total" => 600
                        ]
                        6 => array:2 [▼
                            "sumW" => 150
                            "total" => 150
                        ]
                    ]
                    "total" => 850.28
                ]
                7 => array:3 [▼
                    "sumW" => 30
                    "child" => array:1 [▼
                        5 => array:2 [▼
                            "sumW" => 100
                            "total" => 100
                        ]
                    ]
                    "total" => 130
                ]
            ]
            "total" => 1480.67
        ]
    ]
    "total" => 1480.67
]