按列对行进行分组并对组内的另一列求和
Group rows by column and sum another column within groups
我有一个数组,如下所示:
array(480) {
[0]=>
array(2) {
["tag_id"]=>
string(4) "6291"
["az"]=>
int(5)
}
[1]=>
array(2) {
["tag_id"]=>
string(4) "6291"
["az"]=>
int(4)
}
[2]=>
array(2) {
["tag_id"]=>
string(4) "6311"
["az"]=>
int(4)
}
[3]=>
array(2) {
["tag_id"]=>
string(4) "6427"
["az"]=>
int(4)
}
如果“Tag_ID”相同,我如何减少数组,以便“az”对“az”的所有值求和?
预期输出:
array(479) {
[0]=>
array(2) {
["tag_id"]=>
string(4) "6291"
["az"]=>
int(9)
}
[1]=>
array(2) {
["tag_id"]=>
string(4) "6311"
["az"]=>
int(4)
}
[2]=>
array(2) {
["tag_id"]=>
string(4) "6427"
["az"]=>
int(4)
}
我试过 array_reduce 但无法确定要在其中使用的功能。
非常感谢!
我创建了一些示例代码,理论上只要您知道 tag_id
可能是什么,它就会执行您需要它执行的操作,它使用数组过滤器并检查是否 tag_id
等于您输入的内容:
$arr = array(
array("tag_id" => "6291", "az" => "int(5)"),
array("tag_id" => "6291", "az" => "int(4)"),
array("tag_id" => "6311", "az" => "int(4)"),
);
$results = array_filter($arr, function ($item) {
if ($item["tag_id"] == "6291") {
return true;
}
return false;
});
foreach ($results as $result) {
echo "tag_id = " . $result["tag_id"];
echo "az = " . $result["az"] . PHP_EOL;
}
您必须使用 array_walk()
来修改数组。 array_reduce()
是计算单个值,不改变数组本身。
我会这样做:
<?php
$array = [
[
'tag_id' => "6291",
'az' => 5,
],
[
'tag_id' => "6291",
'az' => 4,
],
[
'tag_id' => "6311",
'az' => 4,
],
[
'tag_id' => "6427",
'az' => 4,
]
];
$tag_id_indexes = []; // To store the index of the first tag_id found.
array_walk(
$array,
function ($sub_array, $index) use (&$array, &$tag_id_indexes) {
// Store the index of the first tag_id found.
if (!isset($tag_id_indexes[$sub_array['tag_id']])) {
$tag_id_indexes[$sub_array['tag_id']] = $index;
}
else { // This tag_id already exists so we'll combine it.
// Get the index of the previous tag_id.
$first_tag_id_index = $tag_id_indexes[$sub_array['tag_id']];
// Sum the az value.
$array[$first_tag_id_index]['az'] += $sub_array['az'];
// Remove this entry.
unset($array[$index]);
}
}
);
print "The reduced array but with the original indexes:\n" . var_export($array, true) . "\n";
// If you want new indexes.
$array = array_values($array);
print "The reduced array with new indexes:\n" . var_export($array, true) . "\n";
你可以在这里测试:https://onlinephp.io/c/58a11
这是输出:
The reduced array but with the original indexes:
array (
0 =>
array (
'tag_id' => '6291',
'az' => 9,
),
2 =>
array (
'tag_id' => '6311',
'az' => 4,
),
3 =>
array (
'tag_id' => '6427',
'az' => 4,
),
)
The reduced array with new indexes:
array (
0 =>
array (
'tag_id' => '6291',
'az' => 9,
),
1 =>
array (
'tag_id' => '6311',
'az' => 4,
),
2 =>
array (
'tag_id' => '6427',
'az' => 4,
),
)
您可以自然地使用array_reduce:
$res = array_reduce(
$array,
function($ac, $el) {
$ac[$el['tag_id']] += $el['az'];
return $ac;
},
[]
);
print_r($res);
它将以 tag_id
为键并以 az
为值构建数组:
Warning: Undefined array key 6291
Warning: Undefined array key 6311
Warning: Undefined array key 6427
Array
(
[6291] => 9
[6311] => 4
[6427] => 4
)
当你需要恢复源数组结构时使用array_map
$res = array_map(
fn($k, $v) => ['tag_id' => $k, 'az' => $v],
array_keys($res),
$res
);
我有一个数组,如下所示:
array(480) {
[0]=>
array(2) {
["tag_id"]=>
string(4) "6291"
["az"]=>
int(5)
}
[1]=>
array(2) {
["tag_id"]=>
string(4) "6291"
["az"]=>
int(4)
}
[2]=>
array(2) {
["tag_id"]=>
string(4) "6311"
["az"]=>
int(4)
}
[3]=>
array(2) {
["tag_id"]=>
string(4) "6427"
["az"]=>
int(4)
}
如果“Tag_ID”相同,我如何减少数组,以便“az”对“az”的所有值求和? 预期输出:
array(479) {
[0]=>
array(2) {
["tag_id"]=>
string(4) "6291"
["az"]=>
int(9)
}
[1]=>
array(2) {
["tag_id"]=>
string(4) "6311"
["az"]=>
int(4)
}
[2]=>
array(2) {
["tag_id"]=>
string(4) "6427"
["az"]=>
int(4)
}
我试过 array_reduce 但无法确定要在其中使用的功能。 非常感谢!
我创建了一些示例代码,理论上只要您知道 tag_id
可能是什么,它就会执行您需要它执行的操作,它使用数组过滤器并检查是否 tag_id
等于您输入的内容:
$arr = array(
array("tag_id" => "6291", "az" => "int(5)"),
array("tag_id" => "6291", "az" => "int(4)"),
array("tag_id" => "6311", "az" => "int(4)"),
);
$results = array_filter($arr, function ($item) {
if ($item["tag_id"] == "6291") {
return true;
}
return false;
});
foreach ($results as $result) {
echo "tag_id = " . $result["tag_id"];
echo "az = " . $result["az"] . PHP_EOL;
}
您必须使用 array_walk()
来修改数组。 array_reduce()
是计算单个值,不改变数组本身。
我会这样做:
<?php
$array = [
[
'tag_id' => "6291",
'az' => 5,
],
[
'tag_id' => "6291",
'az' => 4,
],
[
'tag_id' => "6311",
'az' => 4,
],
[
'tag_id' => "6427",
'az' => 4,
]
];
$tag_id_indexes = []; // To store the index of the first tag_id found.
array_walk(
$array,
function ($sub_array, $index) use (&$array, &$tag_id_indexes) {
// Store the index of the first tag_id found.
if (!isset($tag_id_indexes[$sub_array['tag_id']])) {
$tag_id_indexes[$sub_array['tag_id']] = $index;
}
else { // This tag_id already exists so we'll combine it.
// Get the index of the previous tag_id.
$first_tag_id_index = $tag_id_indexes[$sub_array['tag_id']];
// Sum the az value.
$array[$first_tag_id_index]['az'] += $sub_array['az'];
// Remove this entry.
unset($array[$index]);
}
}
);
print "The reduced array but with the original indexes:\n" . var_export($array, true) . "\n";
// If you want new indexes.
$array = array_values($array);
print "The reduced array with new indexes:\n" . var_export($array, true) . "\n";
你可以在这里测试:https://onlinephp.io/c/58a11
这是输出:
The reduced array but with the original indexes:
array (
0 =>
array (
'tag_id' => '6291',
'az' => 9,
),
2 =>
array (
'tag_id' => '6311',
'az' => 4,
),
3 =>
array (
'tag_id' => '6427',
'az' => 4,
),
)
The reduced array with new indexes:
array (
0 =>
array (
'tag_id' => '6291',
'az' => 9,
),
1 =>
array (
'tag_id' => '6311',
'az' => 4,
),
2 =>
array (
'tag_id' => '6427',
'az' => 4,
),
)
您可以自然地使用array_reduce:
$res = array_reduce(
$array,
function($ac, $el) {
$ac[$el['tag_id']] += $el['az'];
return $ac;
},
[]
);
print_r($res);
它将以 tag_id
为键并以 az
为值构建数组:
Warning: Undefined array key 6291
Warning: Undefined array key 6311
Warning: Undefined array key 6427
Array
(
[6291] => 9
[6311] => 4
[6427] => 4
)
当你需要恢复源数组结构时使用array_map
$res = array_map(
fn($k, $v) => ['tag_id' => $k, 'az' => $v],
array_keys($res),
$res
);