递归搜索层级多维数组,匹配列部分值并返回路径对应列值
递归搜索层级数组并返回路径解决方案
嘿,我来帮你搞定这个递归搜索的需求!咱们先明确核心目标:遍历这个嵌套的层级数组,找到所有指定列包含目标值的节点,然后返回从根节点到该匹配节点的另一列(比如Id)组成的完整路径。下面是一步步的实现方案:
首先,整理你的示例数组
先把你给出的层级数组整理成更清晰的格式:
$Array = [ [ 'Id' => 1, 'Title' => 'Some Text1', 'Children' => [ [ 'Id' => 11, 'Title' => 'Some Text11', 'Children' => [ ['Id' => 111, 'Title' => 'Some Text111'], [ 'Id' => 112, 'Title' => 'Some Text112', 'Children' => [['Id' => 1121, 'Title' => 'Some Text1121']] ] ] ], [ 'Id' => 12, 'Title' => 'Some Text12', 'Children' => [['Id' => 121, 'Title' => 'Test Match Text']] ] ] ] ];
递归搜索函数实现
我写了一个通用的递归函数,支持自定义匹配列、路径列,灵活性拉满:
/** * 递归搜索层级数组,匹配指定列的部分值,返回路径上目标列的集合 * @param array $nodes 当前遍历的节点数组 * @param string $searchValue 要匹配的部分值 * @param string $searchColumn 匹配的目标列(比如Title) * @param string $pathColumn 路径要收集的列(比如Id) * @param array $currentPath 递归时传递的当前路径,默认空数组 * @return array 所有符合条件的路径数组 */ function recursiveSearch($nodes, $searchValue, $searchColumn, $pathColumn, $currentPath = []) { $results = []; foreach ($nodes as $node) { // 复制当前路径,避免不同分支互相干扰 $currentNodePath = $currentPath; // 把当前节点的路径列加入路径 $currentNodePath[] = $node[$pathColumn]; // 检查当前节点的搜索列是否包含目标值(strpos区分大小写,要忽略的话换stristr) if (strpos($node[$searchColumn], $searchValue) !== false) { $results[] = $currentNodePath; } // 如果有子节点,继续递归深入 if (!empty($node['Children'])) { $childResults = recursiveSearch($node['Children'], $searchValue, $searchColumn, $pathColumn, $currentNodePath); // 合并子节点的搜索结果 $results = array_merge($results, $childResults); } } return $results; }
示例调用与结果
比如我们要搜索Title中包含Text11的节点,返回对应的Id路径:
$searchResults = recursiveSearch($Array, 'Text11', 'Title', 'Id'); print_r($searchResults);
输出结果会是:
Array ( [0] => Array ( [0] => 1 [1] => 11 ) [1] => Array ( [0] => 1 [1] => 11 [2] => 111 ) [2] => Array ( [0] => 1 [1] => 11 [2] => 112 ) )
实用扩展小技巧
- 如果只需要第一个匹配的路径,可以在找到结果后直接
return [$currentNodePath];,终止递归提升效率。 - 支持正则匹配:把
strpos换成preg_match,比如preg_match("/{$searchValue}/i", $node[$searchColumn])(注意转义正则特殊字符)。 - 兼容无
Children键的节点:可以改成isset($node['Children']) && !empty($node['Children'])来判断子节点是否存在。
内容的提问来源于stack exchange,提问作者jamshid
相关产品推荐
相关产品推荐

