
本文介绍一种高效、可复用的方法:利用 array_count_values() 统计频次,再遍历原数组为每个重复项追加递增序号(如 _1、_2),同时保留非重复项和含特殊标记(如 #75)的原始值不变。
本文介绍一种高效、可复用的方法:利用 `array_count_values()` 统计频次,再遍历原数组为每个重复项追加递增序号(如 `_1`、`_2`),同时保留非重复项和含特殊标记(如 `#75`)的原始值不变。
在实际开发中(如网络设备列表去重、日志归类或表单数据清洗),我们常需对 PHP 数组中的重复字符串进行语义化区分——不是简单删除,而是通过添加唯一后缀(如 _1、 _2)实现可读性标识。关键约束在于:仅对完全相同的原始值编号;含 #75 等修饰符的条目视为独立项,不参与重复判定。
以下是一个健壮、易理解的实现方案:
function renameDuplicatesWithIndex(array $input): array {
// 1. 统计每个值的出现次数(严格全等匹配)
$counts = array_count_values($input);
// 2. 记录每个值当前已分配的序号
$usedCount = [];
// 3. 遍历原数组,构建新结果
$result = [];
foreach ($input as $index => $value) {
if ($counts[$value] > 1) {
// 仅当该值重复时才添加序号后缀
$currentNum = ($usedCount[$value] ?? 0) + 1;
$usedCount[$value] = $currentNum;
$result[$index] = $value . '_' . $currentNum;
} else {
// 非重复项保持原样
$result[$index] = $value;
}
}
return $result;
}
// 示例使用
$devices = [
'QLogic BCM57810 10 Gigabit Ethernet (NDIS VBD Client)',
'Microsoft Network Adapter Multiplexor Driver',
'QLogic BCM57810 10 Gigabit Ethernet (NDIS VBD Client) #75',
'QLogic BCM57810 10 Gigabit Ethernet (NDIS VBD Client)',
];
$renamed = renameDuplicatesWithIndex($devices);
print_r($renamed);
✅ 输出效果:
Array
(
[0] => QLogic BCM57810 10 Gigabit Ethernet (NDIS VBD Client)_1
[1] => Microsoft Network Adapter Multiplexor Driver
[2] => QLogic BCM57810 10 Gigabit Ethernet (NDIS VBD Client) #75
[3] => QLogic BCM57810 10 Gigabit Ethernet (NDIS VBD Client)_2
)
? 核心要点说明:
-
array_count_values()基于完整字符串精确匹配,因此'ABC'与'ABC #75'被视为不同元素; - 使用
$usedCount关联数组动态跟踪每个重复值的已用序号,避免嵌套循环,时间复杂度优化至 O(n); - 函数式封装确保不修改原数组,符合函数式编程最佳实践;
- 若需自定义分隔符(如
-或.)或起始编号(如从0开始),只需微调拼接逻辑即可。
? 注意事项:
- 该方法对空格、大小写、不可见字符(如
\t,\n)敏感,建议预处理(如trim())确保数据一致性; - 如需支持模糊匹配(如忽略末尾
#数字),应先标准化字符串再统计; - 对超大数组(>10万项),可考虑使用生成器或分块处理以控制内存占用。
此方案简洁、可维护、无副作用,适用于各类业务场景下的重复值标注需求。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











