我需要按第一列值(id 列)对索引数组索引数组中的数据进行分组。 在每个组中,我需要找到第二列的总和并找到第三列的总和。
示例输入:
[
[111, 5, 3],
[111, 3, 7],
[111, 2, 1],
[222, 5, 3],
]
期望的结果:
[
111 => [10, 11]
222 => [5, 3]
]
您必须使用循环手动执行此操作。这样的事情应该有效:
$result = array();
foreach( $input as $row) {
$id = array_shift( $row);
foreach( $row as $key => $value) {
$result[ $id ][ $key ] =
( isset( $result[ $id ][ $key ]) ?
$result[ $id ][ $key ] + $value :
$value
);
}
}
输出:
array(2) {
[111]=>
array(2) {
[0]=>
int(10)
[1]=>
int(11)
}
[222]=>
array(2) {
[0]=>
int(5)
[1]=>
int(3)
}
}
演示
保持简单
foreach ($arrays as $array) {
$final[$array[0]] = array(
@$final[$array[0]][0] + $array[1],
@$final[$array[0]][1] + $array[2]
);
}
http://codepad.org/lCCXHjKR
代码
// This is your input.
$Input[] = array(
0=>111, //id
1=>5, //value to ad
2=>3 //value to ad
);
$Input[] = array(
0=>111,
1=>3,
2=>7
);
$Input[] = array(
0=>111,
1=>2,
2=>1
);
$Input[] = array(
0=>222,
1=>5,
2=>3
);
// This is your output.
$Output = array();
for($i=0; $i<count($Input); $i++)
{
$id = $Input[$i][0];
// If key already exists...
if(array_key_exists($id, $Output))
{
// Sum it.
$Output[$id][0] += $Input[$i][1];
$Output[$id][1] += $Input[$i][2];
}
// If not...
else
{
// Initialize it.
$Output[$id][0] = $Input[$i][1];
$Output[$id][1] = $Input[$i][2];
}
}
// This is your output dumped.
print_r($Output);
输出
Array
(
[111] => Array
(
[0] => 10
[1] => 11
)
[222] => Array
(
[0] => 5
[1] => 3
)
)
附加说明
关键是使用 array_key_exists 来检查数组中是否已存在索引。
使用语言构造的简洁现代方法是使用 foreach()
迭代 inout 数组,并在添加相关数据点时利用 null 合并运算符。 这可以防止因尝试向未声明的变量添加值而导致的任何警告。 应避免使用 @
符号来抑制错误,因为它表示愿意忽略来自服务器的有意义的反馈(并且开发人员通常认为不必要的错误抑制会给代码带来难闻的气味)。
代码:(演示)
$result = [];
foreach ($array as $row) {
$result[$row[0]][0] = ($result[$row[0]][0] ?? 0) + $row[1];
$result[$row[0]][1] = ($result[$row[0]][1] ?? 0) + $row[2];
}
var_export($result);
<小时 /> array_reduce()
提供与函数替代相同的结果,这也阻止了在全局范围内声明变量。
代码:(演示)
var_export(
array_reduce(
$array,
function($result, $row) {
$result[$row[0]][0] = ($result[$row[0]][0] ?? 0) + $row[1];
$result[$row[0]][1] = ($result[$row[0]][1] ?? 0) + $row[2];
return $result;
}
)
);