
本文介绍如何在 php 关联数组中,针对相同 id 的多条记录,快速筛选出每组中 year 最大的最新条目,核心思路是先按年份降序排序,再遍历去重保留首次出现项。
本文介绍如何在 php 关联数组中,针对相同 id 的多条记录,快速筛选出每组中 year 最大的最新条目,核心思路是先按年份降序排序,再遍历去重保留首次出现项。
在处理 JSON 解析后的关联数组(如用户、设备或日志数据)时,常需按某个字段(如 ID)分组,并从中提取每个分组内时间最新(如 Year 最大)的一条记录。这种需求常见于报表生成、状态快照或数据去重场景。
最简洁高效的实现方式分为两步:先排序,后去重。具体来说:
-
按
Year降序排序:确保同 ID 的所有记录中,最新年份排在最前; -
遍历并以
ID为键缓存首条匹配项:利用 PHP 数组键唯一性,仅保留每个 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 后有空格,不影响逻辑
];
// 步骤1:按 Year 降序排序(使用太空船操作符 )
usort($data, fn($a, $b) => $b['Year'] $a['Year']);
// 步骤2:构建 ID → 最新记录映射
$latestByIDs = [];
foreach ($data as $row) {
$id = $row['ID'];
// 若该 ID 尚未存入,则保存当前(即最新)记录
if (!isset($latestByIDs[$id])) {
$latestByIDs[$id] = $row;
}
}
// 步骤3:提取纯数值索引数组(保持原始 ID 顺序无关,如需按 ID 升序可 array_sort_by_key)
$result = array_values($latestByIDs);
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
)
)
⚠️ 注意事项:
- 该方法时间复杂度为 O(n log n)(主要消耗在排序),空间复杂度 O(k)(k 为唯一 ID 数量),适用于中等规模数据(万级以内);
- 若原始数据已按年份有序,可跳过
usort(),直接遍历,进一步提升性能; -
isset($array[$key])比array_key_exists()更轻量且语义更贴切(我们关注的是“是否已赋值”,而非“键是否存在但值为 null”); - 如需严格按
ID数值升序输出结果,可在最后添加:uasort($latestByIDs, fn($a, $b) => $a['ID'] $b['ID']); $result = array_values($latestByIDs);
此方案逻辑清晰、无依赖、易维护,是 PHP 中处理“每组取最新”类问题的标准实践。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











