您遇到的问题涉及递归和/或树遍历。RecursiveArrayIterator
PHP 支持使用和对数组进行树遍历RecursiveIteratorIterator
。
要获取所有父数组的所有key,需要从第一层到当前深度获取key。RecursiveIteratorIterator
该方法也支持这一点getSubIterator()
。手册中并没有很好地记录它,所以这里是一个例子:
$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";
}
在这个例子中,首先创建了RecursiveArrayIterator
with your $array
。为了启用树遍历,它被包装到RecursiveIteratorIterator
. 这是以递归方式使用$it
-iterator所必需的。foreach
在foreach
then 内部,将根据您的搜索值检查数组值。如果不匹配,则继续下一个值。
但如果它确实匹配递归迭代器上的getDepth()
andgetSubIterator()
方法,则用于创建键数组。
该示例执行以下输出:
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
在您的场景中,您还希望根据特定值(此处为 string "x"
)过滤迭代器,您可以通过使用RegexIterator
which is a轻松完成此操作FilterIterator
。这就是你的场景:
$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
如您所见,它会针对您感兴趣的值进行过滤。
您可能感兴趣的其他相关问题是: