
本文讲解如何基于二维数组的两个字段(如类别和数值)进行嵌套分组、统计频次,并按“键 值x次数”格式生成可读性强的字符串输出,兼顾代码简洁性与执行效率。
本文讲解如何基于二维数组的两个字段(如类别和数值)进行嵌套分组、统计频次,并按“键 值x次数”格式生成可读性强的字符串输出,兼顾代码简洁性与执行效率。
在 PHP 中处理类似 [['FA', 12.9], ['FA', 12.9], ...] 的二维数据时,若需按第一列(如分组标识)+ 第二列(如数值)联合去重并计数,再格式化为 FA 12.9x3 这类字符串,推荐使用函数式编程思路——array_reduce() 实现清晰、健壮且无副作用的分组聚合。
以下为优化后的完整实现:
$array = [
['FA', 12.9],
['FA', 12.9],
['FB', 12.2],
['FC', 12.3],
['FA', 12.9],
['FB', 12.9],
['FA', 12.4],
];
// 步骤1:使用 array_reduce 构建嵌套计数数组 [group => [value => count]]
$grouped = array_reduce($array, function ($carry, $item) {
[$group, $value] = $item;
$key = (string)$group;
$valStr = (string)$value; // 强制转字符串避免浮点精度导致的键混淆(如 12.90 vs 12.9)
if (!isset($carry[$key])) {
$carry[$key] = [];
}
if (!isset($carry[$key][$valStr])) {
$carry[$key][$valStr] = 0;
}
$carry[$key][$valStr]++;
return $carry;
}, []);
// 步骤2:遍历分组结果,生成格式化字符串
$outputLines = [];
foreach ($grouped as $group => $values) {
foreach ($values as $value => $count) {
$outputLines[] = sprintf('%s %sx%d', $group, $value, $count);
}
}
// 输出结果(每行一条)
echo implode("\n", $outputLines);
✅ 预期输出:
FA 12.9x3 FA 12.4x1 FB 12.2x1 FB 12.9x1 FC 12.3x1
? 关键优化点说明:
- ✅ 避免手动嵌套判断:原代码中多层
if (!array_key_exists(...))易出错且冗长;isset()在array_reduce中更高效、语义更清晰。 - ✅ 浮点安全处理:将数值显式转为字符串
(string)$value,防止12.9和12.90被视为不同键(PHP 数组键自动类型转换可能导致意外行为)。 - ✅ 零初始化保障:直接
$carry[$key][$valStr]++前确保两级键存在,避免未定义索引警告。 - ✅ 解耦逻辑:分组聚合与格式化输出分离,便于单元测试、复用或后续扩展(如排序、过滤)。
? 进阶提示:
若需按字母顺序输出分组、或对同一分组内数值升序排列,可在 foreach ($grouped as ...) 前添加:
uksort($grouped, 'strcmp'); // 按 group 名字排序
foreach ($grouped as $group => $values) {
ksort($values, SORT_NUMERIC); // 按数值升序排
// ...
}
该方案兼具可读性、健壮性与扩展性,是处理此类「双维度分组计数 + 格式化输出」场景的推荐实践。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











