
本文介绍如何在 php 关联数组中,按 id 分组并提取每组中 year 最大的最新记录,核心思路是先降序排序再去重,时间复杂度低、逻辑清晰、代码可读性强。
本文介绍如何在 php 关联数组中,按 id 分组并提取每组中 year 最大的最新记录,核心思路是先降序排序再去重,时间复杂度低、逻辑清晰、代码可读性强。
在处理从 JSON 解析出的关联数组(如用户数据、日志记录或版本信息)时,常需按某个字段(如 ID)分组,并仅保留每组中时间最新(如 Year 最大)的一条记录。例如,原始数据中同一 ID 可能对应多个年份的条目,而我们只关心其“最新快照”。
最直观且高效的解决方案是:先按 Year 降序排序,再遍历并以 ID 为键缓存首次出现的记录。由于已排序,每个 ID 的首次出现即为其最大年份项,天然保证结果正确性。
以下是完整实现代码:
<?php $data = [
['Name' => 'Gary', 'ID' => 1, 'Year' => 2016],
['Name' => 'Miller', 'ID' => 2, 'Year' => 2018],
['Name' => 'Spike', 'ID' => 3, 'Year' => 2019],
['Name' => 'Miller', 'ID' => 2, 'Year' => 2020],
['Name' => 'Gary', 'ID' => 1, 'Year' => 2018],
['Name' => 'Miller', 'ID' => 2, 'Year' => 2019],
['Name' => 'Gary', 'ID' => 1, 'Year' => 2017],
['Name' => 'Spike ', 'ID' => 3, 'Year' => 2020] // 注意:'Spike ' 含尾部空格,实际使用中建议 trim()
];
// 步骤 1:按 Year 降序排序(升序用 $a['Year'] $b['Year'])
usort($data, function ($a, $b) {
return $b['Year'] $a['Year']; // PHP 7+ 强势飞船操作符,简洁安全
});
// 步骤 2:构建 ID → 最新记录映射(利用数组键唯一性)
$latestByid = [];
foreach ($data as $row) {
$id = $row['ID'];
// 首次遇到该 ID 时保存——因已排序,必为最新年份
if (!isset($latestByid[$id])) {
$latestByid[$id] = $row;
}
}
// 步骤 3:提取纯数值索引数组(保持 ID 顺序无关,若需按原始 ID 顺序可后续 ksort + array_values)
$result = array_values($latestByid);
print_r($result);
✅ 输出结果(与预期完全一致):
Array
(
[0] => Array ([Name] => Miller [ID] => 2 [Year] => 2020)
[1] => Array ([Name] => Spike [ID] => 3 [Year] => 2020)
[2] => Array ([Name] => Gary [ID] => 1 [Year] => 2018)
)
? 关键注意事项:
-
排序稳定性:
usort不保证相等元素的相对顺序,但本例中Year相同时无需区分先后,故无影响; -
空格/类型隐患:示例中
'Spike '含末尾空格,若Name参与业务逻辑(如去重或展示),建议预处理:$row['Name'] = trim($row['Name']);; - 性能优势:时间复杂度为 O(n log n)(主要来自排序),远优于嵌套循环的 O(n²) 方案;
-
扩展性提示:若需按多字段(如
ID + Category)分组取最新,可将键改为$key = $row['ID'] . '|' . $row['Category']; - 内存友好:全程仅使用一个辅助数组,不复制原始数据,适合中等规模数据集(万级以内)。
该方法兼顾简洁性、可维护性与执行效率,是 PHP 数组聚合场景下的推荐实践。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











