PHP数组进阶去重:如何移除相似元素(如london与londonn)
PHP数组移除相似重复元素方案
问题背景
给定如下PHP数组:
$a[] = "paris"; $a[] = "london"; $a[] = "paris"; $a[] = "london tour"; $a[] = "london tours"; $a[] = "london"; $a[] = "londonn"; foreach($a as $name) { echo $name; echo '<br>'; }
输出结果:
paris london paris london tour london tours london londonn
已通过array_unique移除完全重复元素:
foreach(array_unique($a) as $name) { echo $name; echo '<br>'; }
得到输出:
paris london london tour london tours londonn
现在需要进一步移除相似元素:
- 保留
london,移除londonn - 保留
london tour,移除london tours
期望最终输出:
paris london london tour
尝试使用similar_text函数但未成功,错误代码如下:
foreach(array_unique($a) as $name) { $test = $a; foreach($test as $test1) { similar_text($name, $test1, $percent); if ($percent > 90) { echo $name; echo '<br>'; } } }
错误输出:
paris paris london london london london tour london tour london tours london tours londonn londonn londonn
正确实现方案
核心思路:
- 先对数组去重,避免重复处理完全相同的元素
- 遍历去重后的数组,逐个判断当前元素是否已经有“更简短的相似原型”存在于结果集中
- 结合字符串包含关系和相似度阈值判断,优先保留更短的基准元素(符合保留原型、移除变体的需求)
实现代码:
// 先对原数组去重 $uniqueArray = array_unique($a); // 存储最终去重后的结果 $result = []; foreach ($uniqueArray as $item) { $shouldKeep = true; // 遍历已筛选的结果,判断当前元素是否是已有元素的相似变体 foreach ($result as $existingItem) { similar_text($item, $existingItem, $similarityPercent); // 两个判断条件:相似度达标 + 当前元素是已有元素的扩展(长度更长/包含已有元素) if ($similarityPercent > 80 && (strlen($item) > strlen($existingItem) || strpos($item, $existingItem) !== false)) { $shouldKeep = false; break; } // 反向判断:如果已有元素是当前元素的变体,则替换为更短的当前元素 if ($similarityPercent > 80 && strlen($existingItem) > strlen($item)) { $result = array_diff($result, [$existingItem]); break; } } if ($shouldKeep) { $result[] = $item; } } // 输出最终结果 foreach ($result as $name) { echo $name; echo '<br>'; }
代码说明
- 先用
array_unique去重,减少后续无效计算 - 遍历每个元素时,和结果集中的已有元素对比相似度,阈值设为80可根据实际场景调整
- 当当前元素是已有元素的高相似度变体时,直接丢弃;若已有元素是变体,则替换为更短的原型元素
- 结合字符串包含关系,能更精准区分原型和变体(比如
london tours包含london tour)
运行上述代码后,输出结果符合预期:
paris london london tour
内容的提问来源于stack exchange,提问作者wp-ap
相关产品推荐
相关产品推荐

