You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP三维数组去重方法 array_unique使用后仍无效

PHP三维数组跨层级去重实现方案

核心需求匹配逻辑

我们要做的是完全保留原数组的两层外层结构,从数组靠前位置开始,优先保留第一次出现的三级关联元素,过滤掉后续跨二级子数组出现的完全相同的重复值,不随意调整原有索引顺序和层级关系。

原有实现失效的原因

你之前尝试使用的array_unique($accessories, SORT_REGULAR)无法达到预期,核心问题在于:

  • 该函数的比对对象是最外层数组的顶层元素,也就是每个完整的二级子数组,根本不会深入到三级元素层面识别跨二级的重复内容
  • 函数执行后会重置最外层数组的索引,无法严格保留原数组的层级结构

可落地的实现代码

通用适配版(不依赖业务主键,判断完全相同的元素)

// 记录已经留存过的三级元素标识
$seenItems = [];
$filteredResult = [];

// 遍历最外层数组,保留原外层索引
foreach ($accessories as $outerIndex => $secondLevelArr) {
    $currentSecondLevel = [];
    foreach ($secondLevelArr as $thirdLevelItem) {
        // 序列化整个三级元素,完全相同的元素序列化结果必然一致
        $itemSign = serialize($thirdLevelItem);
        // 仅留存首次出现的元素
        if (!isset($seenItems[$itemSign])) {
            $seenItems[$itemSign] = true;
            $currentSecondLevel[] = $thirdLevelItem;
        }
    }
    // 将过滤后的二级子数组按原索引存回结果
    $filteredResult[$outerIndex] = $currentSecondLevel;
}

这套逻辑的执行效果和你的预期输出完全匹配:

  • 第一个二级子数组内的id_product=12、id_product=14元素都是首次出现,全部保留
  • 第二个二级子数组内的id_product=16是首次出现正常保留,id_product=14的元素已经在前面的子数组中出现过,会被直接过滤,最终结构和示例预期完全一致

性能优化版(适配业务唯一主键场景)

因为示例里的三级元素有92个字段,如果整个数组数据量很大,序列化整个大数组的性能开销会偏高。如果业务上确定id_product是每个商品元素的唯一标识,可以直接拿商品ID做重复判断标记,省去序列化大数组的开销:

$seenItems = [];
$filteredResult = [];
foreach ($accessories as $outerIndex => $secondLevelArr) {
    $currentSecondLevel = [];
    foreach ($secondLevelArr as $thirdLevelItem) {
        $productId = $thirdLevelItem['id_product'];
        if (!isset($seenItems[$productId])) {
            $seenItems[$productId] = true;
            $currentSecondLevel[] = $thirdLevelItem;
        }
    }
    $filteredResult[$outerIndex] = $currentSecondLevel;
}

注意:这套实现遵循「首次出现优先保留」的规则,也就是靠前位置的重复元素不会被后续同值元素覆盖,完全匹配你示例中的去重规则。

内容的提问来源于stack exchange,提问作者Ahmed guesmi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 05:27:02