按值获取所有数组键



假设我有一个这样的数组:

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 ($array as $key => $value)循环和array_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支持使用RecursiveArrayIteratorRecursiveIteratorIterator遍历数组的树。

要获取所有父数组的所有关键帧,需要从第一个级别获取到当前深度并获取关键帧。RecursiveIteratorIteratorgetSubIterator()方法都支持这一点。手册中并没有很好地记录它,所以这里有一个例子:

$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";
}

在本例中,首先创建带有$arrayRecursiveArrayIterator。为了实现树遍历,它被封装到RecursiveIteratorIterator中。这对于以递归方式将$it迭代器与foreach一起使用是必要的。

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

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

该示例执行以下输出:

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

这与你在问题中的描述相匹配。

因为这些都是迭代器,所以您也可以将其实现到自己的类中。以下Iterator类不仅允许在构造函数中提供的数组上进行树遍历,而且还具有一个名为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;
    }
}

这样它就更容易使用了(可能也适用于其他场景)。所以首先是一些基本的用法示例。遍历数组,显示每个值的所有键。实例化数组的迭代器,并根据每个值输出键:

$it = new ArrayRecursiveKeysIterator($array);
foreach ($it as $value) {
    echo implode(', ', $it->getKeys()), ', ', $value, "n";
}

这将创建以下输出:

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")过滤迭代器,通过使用RegexIteratorFilterIterator)可以很容易地进行过滤。这就是你的场景:

$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

正如你所看到的,它是根据你感兴趣的值进行过滤的

你可能感兴趣的其他相关问题有:

  • RecursiveIteratorIterator如何在php中工作
  • PHP-从面包屑列表的多维关联数组返回父数组
  • 以相反的顺序从单向数组中获取数据

相关内容

  • 没有找到相关文章

最新更新