在不确定深度的多维数组中递归搜索值时获取所有路径索引

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

我有像这样的 N 级阵列

$array = [
    [
        'id' => 67941,
        'parent_id' => 0,
        'name' => 'Requirement',
        'children' => [
            [
                'id' => 67942,
                'parent_id' => 67941,
                'name' => 'Sub Requirement',
                'children' => [
                    [
                        'id' => 67943,
                        'parent_id' => 67942,
                        'name' => 'Sub Sub Requirement',
                    ],
                ],
            ],
        ],
    ],
    //...
];

我想搜索 67943——它位于数组的第 3 个索引级别(实际上是第 5 个级别)。我可以使用

array_walk_recursive()
来查找该值是否存在,但我需要收集导致该值的索引的完整路径,例如
$array[0][0][0]['id']
.

我不能对关卡进行硬编码,我需要一个可以在超过 100 个关卡的阵列上工作的解决方案。

php arrays recursion multidimensional-array iterator
2个回答
0
投票

我对 RecursiveIteratorIterator 类或其表兄弟没有太多经验,但我能够修改this answer以满足您的条件要求。

遍历数组时,如果键是“children”,则不要缓存键。

如果该值为搜索值,则捕获key的当前路径并打破循环。

我不明白你为什么想要

$array[0][0][0]['id']
的返回值,所以我只返回一个包含键的平面数组。

代码:(演示

$needle = 67943;

$ritit = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$result = null;
foreach ($ritit as $leafValue) {
    $path = [];
    foreach (range(0, $ritit->getDepth()) as $depth) {
        $obj = $ritit->getSubIterator($depth);
        $key = $obj->key();
        if ($key !== 'children') {
            $path[] = $key;
        }
        if ($obj->current() === $needle) {
            $result = $path;
            break 2;
        }

    }
}
var_export($result);

输出:

array (
  0 => 0,
  1 => 0,
  2 => 0,
  3 => 'id',
)

-1
投票

这样可以避免使用递归函数,并以广度优先的方式返回匹配的数组。根据您的需要,可以修改它以返回路径的字符串表示形式。

function findNode(array $nodes, $searchValue) {
    while (!empty($nodes)) {
        $node = array_pop($nodes);
        if (isset($node['id']) && ($node['id'] == $searchValue)) {
            // found
            return $node;
        }
        // add any children to the list of nodes to be searched
        if (!empty($node['children']) && is_array($node['children'])) {
            $nodes = array_merge($node['children'], $nodes);
        }
    }

    // not found
    return null;
}

$foundNode = findNode($myArray, 67943);
© www.soinside.com 2019 - 2024. All rights reserved.