
本文详解如何将包含 id 和年份的 php 数组按年份聚合、自动去重并升序排序每个年份对应的 id 列表,最终生成结构清晰、键为年份、值为有序 id 数组的关联数组。
本文详解如何将包含 id 和年份的 php 数组按年份聚合、自动去重并升序排序每个年份对应的 id 列表,最终生成结构清晰、键为年份、值为有序 id 数组的关联数组。
在实际开发中(如处理多条记录的时间维度聚合、报表统计或前端时间轴渲染),我们常需将原始数据按某个字段(如 year)分组,并对子项(如 id)进行去重与排序。本文以一个典型场景为例:给定一个二维数组,每项含 id 和 year,目标是按年份归集所有唯一 ID,并对每个年份下的 ID 升序排列,输出形如 ['2022' => [1], '2020' => [1, 2], '1999' => [1]] 的结构。
以下是一个简洁、可读性强且不依赖高阶函数的实现方案:
<?php function groupItemsByYear($input) {
$groupedByYear = [];
// 遍历原始数组,按 year 构建分组
foreach ($input as $item) {
$year = $item['year'];
$id = $item['id'];
// 若该年份尚未存在,则初始化空数组
if (!array_key_exists($year, $groupedByYear)) {
$groupedByYear[$year] = [];
}
// 追加 id(自动允许重复添加,后续统一去重)
$groupedByYear[$year][] = $id;
}
// 对每个年份下的 ID 数组去重 + 升序排序
foreach ($groupedByYear as $year => &$ids) {
$ids = array_unique($ids); // 去重(保留首次出现的值)
sort($ids, SORT_NUMERIC); // 数值升序排序(关键:避免字符串排序如 "10" 1, 'year' => 1999],
['id' => 1, 'year' => 2022],
['id' => 2, 'year' => 2020],
['id' => 1, 'year' => 2020]
];
$result = groupItemsByYear($items);
print_r($result);
运行结果:
Array
(
[2022] => Array
(
[0] => 1
)
[2020] => Array
(
[0] => 1
[1] => 2
)
[1999] => Array
(
[0] => 1
)
)
✅ 关键要点说明:
- array_unique() 确保同一 ID 在同一年份下仅出现一次(即使原始数据中多次出现);
- sort($ids, SORT_NUMERIC) 强制数值排序,避免默认字符串排序导致 2020
- krsort() 可选调用,使年份键按降序排列(最新年份优先),更符合业务直觉;
- 整个流程无闭包、无 array_reduce 等复杂函数,便于调试与维护,兼容 PHP 5.6+。
⚠️ 注意事项:
- 输入数组必须保证每项均含 id 和 year 键,否则需增加 isset() 校验;
- 若需严格保持原始 ID 类型(如字符串 '001'),请改用 SORT_STRING 并慎用 array_unique(因其会转换类型),此时建议使用 array_values(array_flip(array_flip(...))) 或手动遍历去重;
- 大数据量时(>10 万条),可考虑先 usort 预排序再分组,提升缓存局部性。
该方案兼顾健壮性、可读性与性能,可直接集成至 Laravel、Symfony 或原生项目的数据预处理层。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











