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函数可以实现这一点。你想弄平什么?在每次迭代中,它已经是线性顺序,并且只需要一个特定值的键,所以我认为不需要整平整个数组。