re-index array and add totals

Viewed 40

I'm trying to figure out how to restructure an array and total values by given keys. I currently have an array called $data that is returning this result:

Bill => array:3 [▼
  "01" => array:6 [▼
    "Food " => array:2 [▶]
      hamburger=>array:[
        sales=> 210.00
        purchases=>200.00
      ]
      burrito=>array:[
        sales=> 100.00
        purchases=>40.00
      ]
    "Drink     " => array:2 [▶]
      coke=>array:[
        sales=> 210.00
        purchases=>200.00
      ]
      pepsi=>array:[
        sales=> 100.00
        purchases=>40.00
      ]
    "total" => array:7 [▶]
      sales=>620.00
      purchases=>480.00
  ]
]
Ted => array:3 [▼
  "01" => array:6 [▼
    "Food " => array:2 [▶]
      hamburger=>array:[
        sales=> 110.00
        purchases=>100.00
      ]
      burrito=>array:[
        sales=> 120.00
        purchases=>40.00
      ]
    "Drink     " => array:2 [▶]
      coke=>array:[
        sales=> 110.00
        purchases=>100.00
      ]
      pepsi=>array:[
        sales=> 120.00
        purchases=>40.00
      ]
    "total" => array:7 [▶]
      sales=>460.00
      purchases=>280.00
  ]
]

My issue is that I need to fit this into a laravel blade that is not concerned with bill or ted, but rather totals for everyone. Where the existing keys are "Bill" and "Ted", I would need the new structure to actually be identified by the "01", but I want to total all of the categories within that level. So I would be hoping to get results like this:

"01" =>[▼
  "Food " => array:2 [▶]
    hamburger=>array:[
      sales=> 320.00
      purchases=>300.00
    ]
    burrito=>array:[
      sales=> 220.00
      purchases=>140.00
    ]
  "Drink     " => array:2 [▶]
    coke=>array:[
      sales=> 320.00
      purchases=>300.00
    ]
    pepsi=>array:[
      sales=> 220.00
      purchases=>80.00
    ]
  "total" => array:7 [▶]
    sales=>1080.00
    purchases=>760.00
 ] 

I can easily loop on this like:

foreach($data as $key=> $value){
  foreach($value as $categoryNumber => $categories){
    foreach($categories as $categoryDetails => $details){
  
    }
  }
}

But I'm completely stuck as to how to re-structure this and total by the new indices

2 Answers

I am not sure how you arrived at the above dd();, I am sure there is a better way of collecting these totals prior to arriving here. But now that you are here (say, you received this via an API or whatever), this would make the totals as you mentioned:

$result = [];
foreach ($input as $i) {
    foreach ($i as $group => $n) {
        if (!array_key_exists($group, $result)) $result[$group] = [];
        foreach ($n as $category_name => $category) {
            if (!array_key_exists($category_name, $result[$group])) $result[$group][$category_name] = [];
            foreach ($category as $item_name => $item) {
                if (!array_key_exists($item_name, $result[$group][$category_name])) {
                    $result[$group][$category_name][$item_name] = $item;
                } else {
                    foreach ($item as $purpose => $dollars) {
                        $result[$group][$category_name][$item_name][$purpose] += $dollars;
                    }
                }
            }
        }
    }
}

In each step, I am checking if the array key exists, and if not, creating it. If you ignore those array_key_exists() checks, you'll see that I am simply copying the contents over and summing where necessary.

You do something like this...

<?php
$data = [
    'Bill' => [
        "01" => [
            "Food" => [
                'hamburger' => [
                    'sales' => 210.00,
                    'purchases' => 200.00,
                ],
                'burrito' => [
                    'sales' => 100.00,
                    'purchases' => 40.00,
                ],
            ],
            "Drink" => [
                'coke' => [
                    'sales' => 210.00,
                    'purchases' => 200.00,
                ],
                'pepsi' => [
                    'sales' => 100.00,
                    'purchases' => 40.00,
                ],
            ],
            "total" => [
                'sales' => 620.00,
                'purchases' => 480.00,
            ],
        ]
    ],
    'Ted' => [
        "01" => [
            "Food" => [
                'hamburger' => [
                    'sales' => 110.00,
                    'purchases' => 100.00,
                ],
                'burrito' => [
                    'sales' => 120.00,
                    'purchases' => 40.00,
                ],
            ],
            "Drink" => [
                'coke' => [
                    'sales' => 110.00,
                    'purchases' => 100.00,
                ],
                'pepsi' => [
                    'sales' => 120.00,
                    'purchases' => 40.00,
                ],
            ],
            "total" => [
                'sales' => 460.00,
                'purchases' => 280.00,
            ],
        ]
    ]
];
$finalResults = [];
foreach ($data as $userName => $bills) {
    foreach ($bills as $billIndex => $billParts) {
        if (!array_key_exists($billIndex, $finalResults)) {
            $finalResults[$billIndex] = [
                'total' => [
                    'sales' => 0,
                    'purchases' => 0,
                ]
            ];
        }
        foreach ($billParts as $partIndex => $details) {
            if (!array_key_exists($partIndex, $finalResults[$billIndex])) {
                $finalResults[$billIndex][$partIndex] = [];
            }
            if ($partIndex !== 'total') {
                foreach ($details as $productCode => $productData) {
                    if (!array_key_exists($productCode, $finalResults[$billIndex][$partIndex])) {
                        $finalResults[$billIndex][$partIndex][$productCode] = [
                            'sales' => 0,
                            'purchases' => 0,
                        ];
                    }
                    $finalResults[$billIndex][$partIndex][$productCode]['sales'] += $productData['sales'];
                    $finalResults[$billIndex][$partIndex][$productCode]['purchases'] += $productData['purchases'];
                }
            } else {
                $finalResults[$billIndex][$partIndex]['sales'] += $details['sales'];
                $finalResults[$billIndex][$partIndex]['purchases'] += $details['purchases'];
            }
        }
    }
}
print_r($finalResults);
Related