# php - Calculate totals for each column of a two dimensional array (matrix)

597

Given the array below, how can I create a sum array with matching keys?

``````\$arr = [
['alpha', 1, 2, 3, 4, 5],
['beta', 1, 2, 3, 4, 5],
['gamma', 1, 2, 3, 4, 5],
['delta', 1, 2, 3, 4, 5]
];
``````

This is what I eventually want:

``````['', 4, 8, 12, 16, 20]
``````

Is this the most efficient way?

``````function getArrTotals(\$arr) {
\$arrTotal = array();
foreach (\$arr as \$subArr) {
foreach (\$subArr as \$k => \$v) {
if (is_numeric(\$v)) {
if (!array_key_exists(\$k,\$arrTotal)) {
\$arrTotal[\$k] = 0;
}
\$arrTotal[\$k] = \$arrTotal[\$k] + \$v;
} else {
if (!array_key_exists(\$k,\$arrTotal)) {
\$arrTotal[\$k] = '';
}
}
}
}
return \$arrTotal;
}
``````
118

#### Solution:

Using the new array_column() function of PHP 5.5:

``````\$colCount = count(\$arr[0]);
\$result = array();
for (\$i = 0; \$i < \$colCount; \$i++) {
\$result[] =
array_sum(
array_column(\$arr, \$i)
);
}
var_dump(\$result);
``````

or for earlier versions of PHP

``````\$result = array();
foreach(call_user_func_array('array_map',array_merge(array(NULL),\$arr)) as \$column) {
\$result[] = array_sum(\$column);
}
var_dump(\$result);
``````

Both methods assume the same number of entries in each sub-array

EDIT

Filtering out the non numeric values to return an empty string for the first column:

``````\$colCount = count(\$arr[0]);
\$result = array();
for (\$i = 0; \$i < \$colCount; \$i++) {
\$values = array_filter(
array_column(\$arr, \$i),
'is_numeric'
);
\$result[] = count(\$values) > 0 ? array_sum(\$values) : '';
}
var_dump(\$result);
``````

and

``````\$result = array();
foreach(call_user_func_array('array_map',array_merge(array(NULL),\$arr)) as \$column) {
\$values = array_filter(\$column,
'is_numeric'
);
\$result[] = count(\$values) > 0 ? array_sum(\$values) : '';
}
var_dump(\$result);
``````

If you want a null instead, then simply replace the '' with null

260

#### Solution:

You only need to "transpose" the data (access columns of data as rows) then sum each subset.`array_map(callback_function, ...\$array)` does the transposition. Then`...\$col` collects the parameters (of indeterminant length) as a single array of data. Finally,`array_sum()` sums the subset of data.

Code: (Demo)

``````\$arr = [
['alpha', 1, 2, 3, 4, 5],
['beta', 1, 2, 3, 4, 5],
['gamma', 1, 2, 3, 4, 5],
['delta', 1, 2, 3, 4, 5]
];

var_export(
array_map(fn(...\$col) => array_sum(\$col), ...\$arr)
);
``````

Output:

``````array (
0 => 0,
1 => 4,
2 => 8,
3 => 12,
4 => 16,
5 => 20,
)
``````

If you adamantly want an empty string for the first column's total, you can write a condition in the callback. (Demo)

``````var_export(
array_map(
fn(...\$col) =>
is_numeric(\$col[0])
? array_sum(\$col)
: '',
...\$arr
)
);
``````

People are also looking for solutions to the problem: php - range of numbers from array

Source