Php 按值获取所有数组键

Php 按值获取所有数组键,php,arrays,multidimensional-array,Php,Arrays,Multidimensional Array,假设我有这样一个数组: Array ( [Start] => Array ( [Item 1] => Array ( [0] => Item 1_1 [Item 2_1] => Array ( [Item 2_1_1] => x

假设我有这样一个数组:

Array
(
[Start] => Array
    (
        [Item 1] => Array
            (
                [0] => Item 1_1
                [Item 2_1] => Array
                    (
                        [Item 2_1_1] => x
                    )

                [1] => Item 3_1
            )

        [0] => Item 2
        [1] => Item 3
    )
)

是否有一个php函数可用于获取指向数组中值
x
的路径,也就是说,在这种情况下,结果将是:

Start, Item 1, Item 2_1, Item 2_1_1, x

我目前能想到的唯一方法是大量嵌套的
foreach($key=>array$value)
array\u search()
一起循环

不过,更好的设计是使其成为递归函数,因此使用函数是明智的

function recursiveSearch($key, $array)
{
    foreach ($array as $k => $ar) {
        if (is_array('x', $ar)) {
            return $k . ', ' . array_search('x', $ar);
        } else {
            if ($ar === 'x') {
                return $k
            } else {
                return recursiveSearch($key, $ar);
            }
        }
    }
}

只是一种尝试,不一定是工作或诸如此类的事情。

您遇到的问题涉及递归和/或树遍历。PHP支持使用
RecursiveArrayIterator
recursiveIterator
对数组进行树遍历

要获取所有父数组的所有键,您需要从第一级获取到当前深度并获取键。该方法也支持递归迭代器。手册中没有很好的记录,因此这里有一个例子:

$it = new RecursiveIteratorIterator(
    new RecursiveArrayIterator($array)
);

foreach ($it as $value) {
    if ($value !== 'x') continue;

    $keys  = array();
    $depth = $it->getDepth();
    for ($i = 0; $keys[] = $it->getSubIterator($i)->key(), $depth--; $i++);

    echo implode(', ', $keys), ', ', $value, "\n";
}
在本例中,首先创建带有
$array
递归ArrayIterator
。要启用树遍历,将其包装到递归迭代器中。这对于以递归方式将
$it
-迭代器与
foreach
一起使用是必要的

然后,在
foreach
中,根据搜索值检查数组值。如果不匹配,则继续使用下一个值

但是,如果它与递归迭代器上的
getDepth()
getSubIterator()
方法匹配,则使用递归迭代器上的方法创建键数组

该示例执行以下输出:

 Start, Item 1, Item 2_1, Item 2_1_1, x
Start, Item 1, 0, Item 1_1
Start, Item 1, Item 2_1, Item 2_1_1, x
Start, Item 1, 1, Item 3_1
Start, 0, Item 2
Start, 1, Item 3
符合你在问题中的描述

因为这些是迭代器,所以您也可以将其实现到自己的类中。下面的
迭代器
类不仅允许对构造函数中提供的数组进行树遍历,还具有一个名为
getKeys()
的方法,该方法返回一个包含从最低级别到当前深度的所有键的数组:

/**
 * Class ArrayRecursiveKeysIterator
 */
class ArrayRecursiveKeysIterator extends RecursiveIteratorIterator
{
    /**
     * @param array $array
     */
    public function __construct(array $array)
    {
        parent::__construct(new RecursiveArrayIterator($array));
    }

    /**
     * @return array keys
     */
    public function getKeys()
    {
        for ($k = [], $i = 0, $m = $this->getDepth(); $i <= $m; $i++)
            $k[] = $this->getSubIterator($i)->key();
        return $k;
    }
}
这将创建以下输出:

 Start, Item 1, Item 2_1, Item 2_1_1, x
Start, Item 1, 0, Item 1_1
Start, Item 1, Item 2_1, Item 2_1_1, x
Start, Item 1, 1, Item 3_1
Start, 0, Item 2
Start, 1, Item 3
在您的场景中,您还希望根据特定的值(这里是字符串
“x”
)过滤迭代器,这可以通过使用
RegexIterator
轻松完成,RegexIterator是一个
过滤器操作符。这就是您的场景:

$it     = new ArrayRecursiveKeysIterator($array);
$filter = new RegexIterator($it, '~^x$~');
foreach ($filter as $value) {
    echo implode(', ', $it->getKeys()), ', ', $value, "\n";
}
这里是输出:

Start, Item 1, Item 2_1, Item 2_1_1, x
如您所见,它会根据您感兴趣的值进行过滤

您可能感兴趣的其他相关问题包括:


您可以尝试使用
serialize()
检查图形搜索算法,如BFS和DFS。我认为这个问题每天都在重复@Akam答案没有显示如何获得关键路径
Start,Item 1,Item 2_1,Item 2_1_1
我想我应该看看
array\u walk\u recursive
,或者如果您对SPL的某些功能感兴趣的话。据我所知,没有一个本机PHP函数可以实现这一点。你想弄平什么?在每次迭代中,它已经是线性顺序,并且只需要一个特定值的键,所以我认为不需要整平整个数组。