user647152
user647152

Reputation: 1

Group data in lowest level of a 3d array by a column and sum another column in each group to create a flat associative array

I need to group data in my 3d array by a deep column and sum another deep column to produce a flat, associative array which contains unique values and their sums.

[
  [
    [
      "Product_Name" => "Apple Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ],
    [
      "Product_Name" => "Apple Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ]
  ],
  [
    [
      "Product_Name" => "Pecan Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ]
  ],
  [
    [
      "Product_Name" => "Strawberry Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ],
    [
      "Product_Name" => "Pecan Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ]
  ],
  [
    [
      "Product_Name" => "Lemon Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ],
    [
      "Product_Name" => "Pecan Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ]
  ]
];

I'm trying to group by same Product_Name and also add up the Product_Qty in each group.

Desired result:

[
  'Apple Pie - 8' => 2,
  'Pecan Pie - 8' => 3,
  'Strawberry Pie - 8' => 1,
  'Lemon Pie - 8' => 1,
]

Upvotes: -1

Views: 56

Answers (3)

mickmackusa
mickmackusa

Reputation: 47894

Because the first level can be safely flattened, using a "spread and merge" technique can eliminate the need for a nested loop. Below uses "array destructuring" to only access the column values which will be used.

Code: (Demo)

$result = [];
foreach (
    array_merge(...$array)
    as
    ['Product_Name' => $n, 'Product_Qty' => $q]
) {
    $result[$n] = ($result[$n] ?? 0) + $q;
}
var_export($result);

Without flattening, a nested loop with arrat destructuring can look like this: (Demo)

$result = [];
foreach ($array as $set) {
    foreach ($set as ['Product_Name' => $n, 'Product_Qty' => $q]) {
        $result[$n] = ($result[$n] ?? 0) + $q;
    }
}
var_export($result);

Upvotes: 0

Yogendrasinh
Yogendrasinh

Reputation: 895

If you want to get all data as in array now then you can run below code.

$finalArray = array();
$product_name_arr = array();
foreach ($array as $key => $value) {
    foreach ($value as $sub_key => $sub_value) {
        if(in_array($sub_value['Product_Name'], $product_name_arr)){
            foreach ($finalArray as $fa_key => $fa_value) {
                if($fa_value['Product_Name'] == $sub_value['Product_Name']){
                    $finalArray[$fa_key]['Product_Qty'] = $finalArray[$fa_key]['Product_Qty'] + $sub_value['Product_Qty'];
                }
            }
        } else {
            $product_name_arr[] = $sub_value['Product_Name'];
            $finalArray[] = $sub_value;
        }
    }
}

Upvotes: 0

Jonathan Gagne
Jonathan Gagne

Reputation: 4379

You can create a double loop and sum all value of every different product under a different array key as below:

$myArr = [
  0 => [
    0 => [
      "Product_Name" => "Apple Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ],
    1 => [
      "Product_Name" => "Apple Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ]
  ],
  1 => [
    0 => [
      "Product_Name" => "Pecan Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ]
  ],
  2 => [
    0 => [
      "Product_Name" => "Strawberry Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ],
    1 => [
      "Product_Name" => "Pecan Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ]
  ],
  3 => [
    0 => [
      "Product_Name" => "Lemon Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ],
    1 => [
      "Product_Name" => "Pecan Pie - 8",
      "Product_Qty" => 1,
      "Product_Cat" => "Pies"
    ]
  ]
];

$total = [];

foreach($myArr as $group){
  foreach($group as $item){
    $total[$item["Product_Name"]] = isset($total[$item["Product_Name"]]) ? $total[$item["Product_Name"]] + $item["Product_Qty"] : $item["Product_Qty"];
  }
}

var_dump($total);

It will provide that total:

array(4) {
  ["Apple Pie - 8"]=>
  int(2)
  ["Pecan Pie - 8"]=>
  int(3)
  ["Strawberry Pie - 8"]=>
  int(1)
  ["Lemon Pie - 8"]=>
  int(1)
}

Upvotes: 2

Related Questions