递归搜索分层多维数组以查找列中的部分值匹配,并返回途中找到的另一列中的值

问题描述 投票:0回答:2

我的项目中有一个分层数组,如下所示:

$Array = array(
    array(
        'Id' => 1,
        'Title' => 'Some Text1',
        'Children' => array(
            array(
                'Id' => 11,
                'Title' => 'Some Text11',
                'Children' => array(
                    array(
                        'Id' => 111,
                        'Title' => 'Some Text111',
                    ),
                    array(
                        'Id' => 112,
                        'Title' => 'Some Text112',
                        'Children' => array(
                            array(
                                'Id' => 1121,
                                'Title' => 'Some Text1121',
                            )
                        )
                    )
                )
            ),
            array(
                'Id' => 12,
                'Title' => 'Some Text12',
                'Children' => array(
                    array(
                        'Id' => 121,
                        'Title' => 'Some Text121',
                    )
                )
            )
        )
    ),
    array(
        'Id' => 2,
        'Title' => 'Some Text2',
    )
);

我想搜索带有传入字符串(例如

Title
)的
Some Text1121
列,并返回由
Id
值组成的路径。

如果搜索的是

Some Text1121
,我想返回:

1 -> 11 -> 112 -> 1121

或者当我搜索“Some”字符串时,返回数组中的所有 Id 路径。

php arrays recursion multidimensional-array hierarchical-data
2个回答
2
投票

我很快就给你写了一些东西。它并不完美,但你明白了:

<?php

function searchRec($haystack, $needle, $pathId = Array(), $pathIndex = Array()) {
    foreach($haystack as $index => $item) {
        // add the current path to pathId-array
        $pathId[] = $item['Id'];
        // add the current index to pathIndex-array
        $pathIndex[] = $index;
        // check if we have a match
        if($item['Title'] == $needle) {
            // return the match
            $returnObject = new stdClass();
            // the current item where we have the match
            $returnObject->match = $item;   
            // path of Id's (1, 11, 112, 1121)
            $returnObject->pathId = $pathId; 
            // path of indexes (0,0,1,..) - you might need this to access the item directly
            $returnObject->pathIndex = $pathIndex; 
            return $returnObject;
        }

        if(isset($item['Children']) && count($item['Children']>0)) {
            // if this item has children, we call the same function (recursively) 
            // again to search inside those children:
            $result = searchRec($item['Children'], $needle, $pathId, $pathIndex);
            if($result) {
                // if that search was successful, return the match-object
                return $result;
            }
        }
    }
    return false;
}

// useage:
$result = searchRec($Array, "Some Text11");
var_dump($result);

// use 
echo implode(" -> ", $result->pathId);
// to get your desired 1 -> 11 -> 112

编辑:重写以使函数实际上返回一些东西。现在它返回一个带有匹配项的对象、Id 的路径和(数组)索引的路径。


0
投票

要在分层数组中的任何级别上搜索部分匹配,请使用递归方法并搜索合格的子字符串。 当找到匹配时,将累积的关键路径推送到结果数组中,该结果数组将返回到调用脚本。

此脚本将返回一个包含零个或多个合格标题的 id 路径的数组。 演示

function pathFinder(array $array, string $find, string $path = ''): array {
    $paths = [];
    foreach ($array as $item) {
        $currentPath = $path . ($path ? ' -> ' : '') . $item['Id'];

        if (str_contains($item['Title'], $find)) {
            $paths[] = $currentPath;
        }

        if (isset($item['Children'])) {
            array_push(
                $paths,
                ...pathFinder($item['Children'], $find, $currentPath)
            );
        }
    }
    return $paths;
}
var_export(
    pathFinder($array, 'Some Text111')
);
© www.soinside.com 2019 - 2024. All rights reserved.