PHP关联数组去重:移除prep_first与prep_second互换的重复元素
PHP过滤关联数组中的反向重复元素
需求是处理关联数组时,删除存在反向配对的重复元素——当元素A的prep_first等于元素B的prep_second,且元素A的prep_second等于元素B的prep_first时,保留先出现的元素,删除后出现的反向元素。
示例输入数组:
$array = [ [ 'description' => '...', 'prof' => '...', 'risk' => 'high', 'prep_first' => 'potassium', 'prep_second' => 'oxygen' ], [ 'description' => '...', 'prof' => '...', 'risk' => 'high', 'prep_first' => 'ethanol', 'prep_second' => 'sodium' ], [ 'description' => '...', 'prof' => '...', 'risk' => 'high', 'prep_first' => 'oxygen', 'prep_second' => 'potassium' ] ];
期望输出数组:
[ [ 'description' => '...', 'prof' => '...', 'risk' => 'high', 'prep_first' => 'potassium', 'prep_second' => 'oxygen' ], [ 'description' => '...', 'prof' => '...', 'risk' => 'high', 'prep_first' => 'ethanol', 'prep_second' => 'sodium' ] ];
分析你的代码问题
你尝试的双层循环存在几个明显问题:
- 变量名错误:
$res[] = $val;中的$val未定义,应该是$value - 逻辑判断错误:条件
$first !== $second1 && $second !== $first1会把所有不满足反向配对的元素重复添加,导致结果数组出现大量重复项 - 没有记录已保留的元素,无法正确过滤后续的反向重复项
正确实现方法
核心思路是用一个辅助数组记录已经处理过的“配对标识”:将每个元素的prep_first和prep_second按固定规则(比如字母排序)拼接成唯一键,这样反向配对的元素会生成相同的键。遍历数组时,只保留第一次出现该键的元素。
代码实现:
$res = []; $seen = []; foreach ($array as $item) { // 生成排序后的配对键,确保反向配对的元素生成相同的键 $pair = [$item['prep_first'], $item['prep_second']]; sort($pair); $key = implode('-', $pair); // 如果该键未被记录过,就保留当前元素并标记键已存在 if (!isset($seen[$key])) { $seen[$key] = true; $res[] = $item; } } // 输出结果 print_r($res);
代码说明
- 生成唯一配对键:通过对
prep_first和prep_second排序后拼接,确保potassium-oxygen和oxygen-potassium生成相同的键oxygen-potassium - 记录已处理的键:用
$seen数组存储已经保留过的配对键,避免重复添加反向元素 - 遍历过滤:只保留第一次出现该配对键的元素,后续的反向重复元素会被跳过
内容的提问来源于stack exchange,提问作者Andrey
相关产品推荐
相关产品推荐

