michael
michael

Reputation: 4483

Sum columnar data in the 3rd level of a multidimensional array

If I have a multi dimensional array in PHP like so...

    [0] => Array
    (
        [url] => http://domain1.com
        [domain] => domain1.com
        [values] => Array
            (
                [character_length] => 25
                [word_count] => 7
            )

    )

    [1] => Array
    (
        [url] => http://domain2.com
        [domain] => domain2.com
        [values] => Array
            (
                [character_length] => 30
                [word_count] => 7

    )

How can I merge them to produce....

    [0] => Array
    (
        [url] => *can be anything*
        [domain] => *can be anything*
        [values] => Array
            (
                [character_length] => 55
                [word_count] => 14
            )

    )

Upvotes: 3

Views: 19164

Answers (4)

mickmackusa
mickmackusa

Reputation: 47894

Because your task requires the data structure to have a changed element count, the most appropriate function to iterate with is array_reduce().

Preserve the first row as the element to receive all subsequent numeric values. Then after the first row, merely add the new column values to the stored column values.

Code: (Demo)

var_export(
    array_reduce(
        $array,
        function($result, $row) {
            if (!isset($result)) {
                $result = $row;
            } else {
                $result['values']['character_length'] += $row['values']['character_length'];
                $result['values']['word_count'] += $row['values']['word_count'];
            }
            return $result;
        }
    )
);

To preserve the last occurring element's url and domain values, return the row with the previously stored sums added to the current row.

Code: (Demo)

var_export(
    array_reduce(
        $array,
        function($result, $row) {
            $row['values']['character_length'] += ($result['values']['character_length'] ?? 0);
            $row['values']['word_count'] += ($result['values']['word_count'] ?? 0);
            return $row;
        }
    )
);

If you just want to get the two totals, you could call array_sum() on the columnar values to populate a flat, indexed array. (Demo)

var_export(
    array_map(
        fn(...$col) => array_sum($col),
        ...array_values(array_column($array, 'values'))
    )
);
// [55, 14]

Upvotes: 0

Faisal
Faisal

Reputation: 4765

You can do this using array_sum() and array_map() funtion like below:

$totalCharacterLength = array_sum(array_map(function($item) { 
    return $item['values']['character_length']; 
}, $totalCharacterLength));

$totalWordCount = array_sum(array_map(function($item) { 
    return $item['values']['word_count']; 
}, $totalWordCount));

Upvotes: 1

Gumbo
Gumbo

Reputation: 655239

Just do a simple foreach on all items and sum the values:

$values = array(
    'character_length' => 0,
    'word_count'       => 0
);
foreach ($array as $item) {
    $values['character_length'] += $item['values']['character_length'];
    $values['word_count']       += $item['values']['word_count'];
}

Upvotes: 5

Andy
Andy

Reputation: 3171

I don't think there's any built-in function that would let you sum the values of a multidimensional array. However, here's a way of doing it using a lambda-style function.

Let's suppose this is your array:

 [items] => Array
        (
            [0] => Array
                (
                    [ID] => 11
                    [barcode] => 234334
                    [manufacturer] => Dell
                    [model] => D630
                    [serial] => 324233
                    [current_value] => 1100.00
                )

            [1] => Array
                (
                    [ID] => 22
                    [barcode] => 323552
                    [manufacturer] => Dell
                    [model] => D630
                    [serial] => 234322
                    [current_value] => 1500.00
                )

        )

You could create a function that you could pass values to:

$array_value_sum = create_function('$array,$key', '$total = 0; foreach($array as $row) $total = $total + $row[$key]; return $total;');

And then use it like so:

echo "Total Current Value" . $array_value_sum($obj['items'], 'current_value');

Upvotes: 7

Related Questions