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

PHP:在深层多维数组中查找元素并修改所有父级元素

解决多维数组中匹配节点及父级添加标记的问题

我明白你的需求啦——要在深度可变的多维数组里,找到所有包含userId的元素,然后给这个元素以及它每一级的父数组都加上[show] => true,而且多个匹配项都要处理对应的父级。之前的递归没成功,大概率是没处理好“向上传递标记”的逻辑,我来给你一个可行的方案。

需求回顾

先把你的原数组和期望结果用代码块整理一下,方便对照:

原数组(PHP格式)

$originalArray = [
    [
        'id' => 3,
        'parent_id' => 0,
        'ownerEntityId' => 2,
        'children' => [
            [
                'id' => 15,
                'parent_id' => 3,
                'ownerEntityId' => 14,
                'children' => [
                    ['id' => 17, 'parent_id' => 15, 'ownerEntityId' => '', 'userId' => 2],
                    ['id' => 18, 'parent_id' => 15, 'ownerEntityId' => ''],
                    ['id' => 19, 'parent_id' => 15, 'ownerEntityId' => ''],
                ]
            ],
            ['id' => 11, 'parent_id' => 3, 'ownerEntityId' => ''],
        ]
    ],
    [
        'id' => 26,
        'parent_id' => 1,
        'ownerEntityId' => '',
        'children' => [
            ['id' => 23, 'parent_id' => 26, 'ownerEntityId' => 24],
            ['id' => 41, 'parent_id' => 26, 'ownerEntityId' => ''],
        ]
    ]
];

期望结果

处理后,包含userId=2的元素(id=17),以及它的父级(id=15、id=3)都会被加上show => true,其他不相关的节点不受影响。

解决方案:递归+向上标记传递

核心思路是:递归遍历数组时,返回一个标记(当前分支是否存在匹配的userId元素),如果子分支有匹配,当前节点就需要添加show标记,同时把这个标记传递给父级,让父级也添加标记。

这里用PHP实现(因为你的数组是PHP格式),代码如下:

function markMatchingNodes(&$node) {
    $hasMatchingChild = false;

    // 检查当前节点是否包含userId,是则添加标记并标记有匹配
    if (isset($node['userId'])) {
        $node['show'] = true;
        $hasMatchingChild = true;
    }

    // 递归处理子节点(如果有children)
    if (isset($node['children']) && is_array($node['children'])) {
        foreach ($node['children'] as &$child) {
            // 如果子节点分支有匹配,当前节点的标记设为true
            if (markMatchingNodes($child)) {
                $hasMatchingChild = true;
            }
        }
        unset($child); // 释放引用,避免后续操作出错
    }

    // 如果当前分支有匹配,且当前节点还没加show标记,就加上
    if ($hasMatchingChild && !isset($node['show'])) {
        $node['show'] = true;
    }

    // 返回标记,告诉父节点当前分支是否有匹配
    return $hasMatchingChild;
}

// 遍历顶层数组,处理每个节点
foreach ($originalArray as &$topNode) {
    markMatchingNodes($topNode);
}
unset($topNode);

代码解释

  1. 传引用参数:用&$node直接修改原数组,不需要额外返回新数组,效率更高。
  2. 匹配检查:先判断当前节点是否有userId,如果有直接加show,并标记$hasMatchingChild为true。
  3. 递归子节点:遍历children数组,递归调用函数,子函数返回true说明子分支有匹配,当前节点的$hasMatchingChild也要设为true。
  4. 添加父级标记:如果$hasMatchingChild为true,且当前节点还没加show,就添加上,确保父级也被标记。
  5. 返回标记:把$hasMatchingChild返回给父级,让父级也执行添加标记的逻辑。

这个方案能处理多个匹配项的情况,比如如果另一个子节点也有userId,它的所有父级都会被正确加上show => true。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:14:10