Arnas Pečelis
Arnas Pečelis

Reputation: 1008

While looping over a 3d array, update each 'total' value by summing the previous total and the current 'count' value

I have an array:

[
    '2015-09-23' => [
        'user' => [13, 12],
        'count' => [
            'count' => 2,
            'total' => 2,
        ],
    ],
    '2015-09-24' => [
        'user' => [14],
        'count' => [
            'count' => 1,
            'total' => 1,
        ],
    ],
    '2015-09-25' => [
        'user' => [15],
        'count' => [
            'count' => 1,
            'total' => 1,
        ],
    ],
    '2015-09-26' => [
        'user' => [16],
        'count' => [
            'count' => 1,
            'total' => 1,
        ],
    ],
    '2015-09-27' => [
        'user' => [17, 18],
        'count' => [
            'count' => 2,
            'total' => 2,
        ],
    ],
    '2015-09-28' => [
        'user' => [19, 20, 21, 22, 23, 24, 25, 26, 27, 28],
        'count' => [
            'count' => 10,
            'total' => 10,
        ],
    ],
]

My vision is to increase every item's ['total'] by the value of the previous item's total plus the cirrent item's ['count']. For example if previous value was 2 and current value is 2, so total will be 4. If next value is 1, so it will be 5.

This is my latest attempt:

$arr_keys = array_keys($this->tmp_data['month_users_formatted']);
foreach ( array_keys($arr_keys) as $key ) {
    $this_value = $this->tmp_data['month_users_formatted'][$arr_keys[$key]];
    if ( isset($this->tmp_data['month_users_formatted'][$arr_keys[$key - 1]]) ){
        $prev_value = $this->tmp_data['month_users_formatted'][$arr_keys[$key - 1]];
        $this_value['count']['total'] = $this_value['count']['total'] + $prev_value['count']['total'];
    }
}

Desired result:

Array
(
    [2015-09-23] => Array
        (
            [user] => Array
                (
                    [0] => 13
                    [1] => 12
                )

            [count] => Array
                (
                    [count] => 2
                    [total] => 2
                )

        )

    [2015-09-24] => Array
        (
            [user] => Array
                (
                    [0] => 14
                )

            [count] => Array
                (
                    [count] => 1
                    [total] => 3
                )

        )

    [2015-09-25] => Array
        (
            [user] => Array
                (
                    [0] => 15
                )

            [count] => Array
                (
                    [count] => 1
                    [total] => 4
                )

        )

    [2015-09-26] => Array
        (
            [user] => Array
                (
                    [0] => 16
                )

            [count] => Array
                (
                    [count] => 1
                    [total] => 5
                )

        )

    [2015-09-27] => Array
        (
            [user] => Array
                (
                    [0] => 17
                    [1] => 18
                )

            [count] => Array
                (
                    [count] => 2
                    [total] => 7
                )

        )

    [2015-09-28] => Array
        (
            [user] => Array
                (
                    [0] => 19
                    [1] => 20
                    [2] => 21
                    [3] => 22
                    [4] => 23
                    [5] => 24
                    [6] => 25
                    [7] => 26
                    [8] => 27
                    [9] => 28
                )

            [count] => Array
                (
                    [count] => 10
                    [total] => 17
                )

        )

)

Upvotes: 0

Views: 67

Answers (3)

mickmackusa
mickmackusa

Reputation: 47864

A functional-style approach can preserve the previous itwration's total as a static variable so that the next iteration can access it.

Code: (Demo) (Condensed Assignments)

var_export(
    array_map(
        function ($set) {
            static $prev = 0;
            $set['count']['total'] += $prev;
            $prev = $set['count']['total'];
            return $set;
        },
        $array
    )
);

Or you can use array destructuring to access the count values and modify the total values by reference.

Code: (Demo) (Not Condensed Assignments)

$total = 0;
foreach ($array as ['count' => ['count' => $c, 'total' => &$t]]) {
    $t = $total += $c;
} 
var_export($array);

Upvotes: 0

Cédric
Cédric

Reputation: 411

You can use foreach and set var by reference :

$muf = $this->tmp_data['month_users_formatted'];
$total = 0;
foreach($muf as &$month){
  $month['count']['total']+=$total;
  $total+= $month['count']['total'];
}

Upvotes: 0

Cameron Spanos
Cameron Spanos

Reputation: 250

    $total = 0;
    foreach($countsAndTotals as $key => $countAndTotal) {
        $total += $countAndTotal['count']['count'];
        $countsAndTotals[$key]['count']['total'] = $total;
    }

    print_r($countsAndTotals);

This will take the array and add up all the count values and then replace the total values with the $total variable.

Upvotes: 1

Related Questions