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

如何过滤层级组合数组,移除被其他条目完全包含的子集条目

如何过滤层级组合数组,移除被其他条目完全包含的子集条目

嘿,我来帮你搞定这个层级数组过滤的问题!先把需求掰扯清楚:你手里有一组公司层级的组合数组,每个条目是关联数组,层级顺序是division > department > team,有些层级可能是null。现在要剔除那些被其他条目完全覆盖的子集条目,只保留最具体的、没有更细化对应条目的组合——说白了就是,如果某个条目存在一个更具体的“子条目”(包含它的所有非null层级,还多了其他具体层级),那这个父条目就该被删掉。

比如你给的示例里:

  • ["division" => "division1"]被后面的division1+department10+team85、division1+null+team91这些更具体的条目覆盖了,所以要移除;
  • ["division" => "division1", "department" => "department10"]被division1+department10+team85覆盖,也得删掉;
  • 而division1+null+team91、division1+null+team92这些没有更具体的条目对应,就保留下来。

接下来给你一个可行的实现思路和代码示例(用PHP写的,因为你的示例是PHP风格的数组):

实现思路

  1. 先明确层级的优先级顺序:division > department > team,这是判断子集的基础;
  2. 写一个辅助函数,用来判断条目A是否是条目B的子集:
    • 检查A的所有非null层级,是否和B的对应层级值完全一致;
    • 同时B必须比A更具体——也就是B至少有一个层级是有值(非null),而A的对应层级是null或者不存在;
  3. 遍历原数组,对每个条目,检查是否存在其他条目让它成为子集,如果存在就丢弃,否则保留。

代码实现

// 定义层级顺序,按从高到低排列
$hierarchyOrder = ['division', 'department', 'team'];

/**
 * 判断条目$a是否是条目$b的子集(即$b比$a更具体,且覆盖$a的所有非null层级)
 */
function isSubset(array $a, array $b, array $hierarchy) {
    // 第一步:检查$a的所有非null层级是否都和$b的对应值一致
    foreach ($hierarchy as $level) {
        $aVal = $a[$level] ?? null;
        $bVal = $b[$level] ?? null;
        if ($aVal !== null && $aVal !== $bVal) {
            return false;
        }
    }
    
    // 第二步:检查$b是否比$a更具体(至少有一个层级$a是null,$b有值)
    $hasMoreSpecific = false;
    foreach ($hierarchy as $level) {
        $aVal = $a[$level] ?? null;
        $bVal = $b[$level] ?? null;
        if ($aVal === null && $bVal !== null) {
            $hasMoreSpecific = true;
            break;
        }
    }
    
    return $hasMoreSpecific;
}

// 你的原始数组
$originalArray = [
    ["division" => "division1"],
    ["division" => "division2"],
    ["division" => "division1", "department" => "department10"],
    ["division" => "division1", "department" => null, "team" => "team91"],
    ["division" => "division1", "department" => "department10", "team" => "team85"],
    ["division" => "division3", "department" => "department999"],
    ["division" => "division2", "department" => "department33"],
    ["division" => "division1", "department" => null, "team" => "team92"],
];

// 过滤数组
$filteredArray = [];
foreach ($originalArray as $currentItem) {
    $shouldKeep = true;
    foreach ($originalArray as $otherItem) {
        // 跳过自身比较
        if ($currentItem === $otherItem) {
            continue;
        }
        // 如果当前条目是另一个条目的子集,标记为不保留
        if (isSubset($currentItem, $otherItem, $hierarchyOrder)) {
            $shouldKeep = false;
            break;
        }
    }
    if ($shouldKeep) {
        $filteredArray[] = $currentItem;
    }
}

// 输出结果
print_r($filteredArray);

运行这段代码后,得到的结果就是你期望的数组:

Array
(
    [0] => Array
        (
            [division] => division1
            [department] => 
            [team] => team91
        )

    [1] => Array
        (
            [division] => division1
            [department] => 
            [team] => team92
        )

    [2] => Array
        (
            [division] => division1
            [department] => department10
            [team] => team85
        )

    [3] => Array
        (
            [division] => division3
            [department] => department999
        )

    [4] => Array
        (
            [division] => division2
            [department] => department33
        )
)

小优化提示

如果你的数组很大,上面的双重循环效率可能不高。可以先把数组按“非null层级的数量”从多到少排序,这样在检查的时候,一旦找到一个更具体的条目,就可以直接终止检查,能节省不少时间~

备注:内容来源于stack exchange,提问作者pileup

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 08:49:37