Reduce arrays inside array of object

I have this array:

Collection {#319 ▼
  #items: array:6 [▼
    "Seccion 1 Pregunta 1" => array:3 [▼
      "satisfactory" => 2
      "unsatisfactory" => 0
      "total" => 2
    ]
    "Seccion 1 Pregunta 2" => array:3 [▼
      "satisfactory" => 2
      "unsatisfactory" => 0
      "total" => 2
    ]
    "Seccion 1 pregunta 3" => array:3 [▼
      "satisfactory" => 0
      "unsatisfactory" => 1
      "total" => 1
    ]
    "Seccion 2 pregunta 1" => array:3 [▼
      "satisfactory" => 3
      "unsatisfactory" => 0
      "total" => 3
    ]
    "Seccion 2 pregunta 2" => array:3 [▼
      "satisfactory" => 1
      "unsatisfactory" => 1
      "total" => 2
    ]
    "Commentarios seccion 2" => array:3 [▼
      "satisfactory" => 0
      "unsatisfactory" => 0
      "total" => 0
    ]
  ]
}

And I would like to get the sum of all the satisfactory, unsatisfactory and total values. Something like:

Collection {#319 ▼
    #items: array:3 [▼
          "satisfactory" => 8
          "unsatisfactory" => 2
          "total" => 10
    ]
}

Upvotes: 0

Views: 176

Answers (4)

The fourth bird
The fourth bird

Reputation: 163362

You could also use array_reduce and pass an array with the keys and values set to 0 as a start value.

$result = array_reduce($arrays, function($carry, $item){
    $carry["satisfactory"] += $item["satisfactory"];
    $carry["unsatisfactory"] += $item["unsatisfactory"];
    $carry["total"] += $item["total"];
    return $carry;
}, ["satisfactory" => 0, "unsatisfactory" => 0, "total" => 0]);

print_r($result);

That would give you:

Array
(
    [satisfactory] => 8
    [unsatisfactory] => 2
    [total] => 10
)

Upvotes: 1

parker_codes
parker_codes

Reputation: 3397

If you know the keys you want, just do:

[
    'satisfactory'   => $collection->sum('satisfactory'),
    'unsatisfactory' => $collection->sum('unsatisfactory'),
    'total'          => $collection->sum('total')
]

If you're not sure what the keys will be, do a loop over the first item's keys to create a similar array as above. If you need this as a collection, just do:

$newCollection = collect( ... array from above ... );

Upvotes: 3

Max Heyer
Max Heyer

Reputation: 135

You can use array_walk:

$data = [
"Seccion 1 Pregunta 1" => [
  "satisfactory" => 2,
  "unsatisfactory" => 0,
  "total" => 2
],
"Seccion 1 Pregunta 2" => [
  "satisfactory" => 2,
  "unsatisfactory" => 0,
  "total" => 2
],
"Seccion 1 pregunta 3" => [
  "satisfactory" => 0,
  "unsatisfactory" => 1,
  "total" => 1
],
"Seccion 2 pregunta 1" => [
  "satisfactory" => 3,
  "unsatisfactory" => 0,
  "total" => 3
],
"Seccion 2 pregunta 2" => [
  "satisfactory" => 1,
  "unsatisfactory" => 1,
  "total" => 2
],
"Commentarios seccion 2" => [
  "satisfactory" => 0,
  "unsatisfactory" => 0,
  "total" => 0
]
];

$total = array('satisfactory' => 0, 'unsatisfactory' => 0, 'total' => 0);

array_walk($data, function($v) use (&$total) {
   $total['satisfactory'] += $v['satisfactory'];
    $total['unsatisfactory'] += $v['unsatisfactory'];
    $total['total'] += $v['total'];
});

Upvotes: 1

Kyle Wardle
Kyle Wardle

Reputation: 830

You can try something like:

$totals = array();
foreach($array as $key => $val) {
    $totals[$key] += $val;
}

Upvotes: 2

Related Questions