我有一个如下所示的数组,数组的大小和元素不是固定的,它完全动态生成
array(
'marketplace' => array(
'browse request' => array('request type 1', 'request type 2'),
'browse lab',
),
'marketplace2' => array('browse request2', 'browse lab2'),
'submitrequest' => array(''),
'aboutus' => array('')
)
我想获取从给定子节点到根节点的路径
让我们说'request type 2'
那么这条路将是'marketplace -> browse request -> request type 2'
再'submitrequest'
,路径就会'submitrequest'
任何帮助将不胜感激。谢谢
如果您的输入是唯一的字符串,因此可以清楚地识别,您只需将值(以及您添加的:键)与字符串进行比较,如果找到,则获取路径:
$string = 'request type 2';
$path = NULL;
$it = new RecursiveIteratorIterator(
new RecursiveArrayIterator($array), RecursiveIteratorIterator::SELF_FIRST
);
foreach ($it as $key => $value) {
if ($key !== $string and $value !== $string) {
continue;
}
$path = [$string];
for ($count = $it->getDepth(); $count && $count--;) {
array_unshift($path, $it->getSubIterator($count)->key());
}
$path = implode(' -> ', $path);
break;
}
var_dump($path); # string(47) "marketplace -> browse request -> request type 2"
类似/相关问答:
- 按值获取所有数组键
- PHP - 从面包屑列表的多维关联数组返回父级数组
- 以相反的顺序从单向数组获取数据
- 递归迭代器迭代器在 PHP 中如何工作?
较早的回答:你可能在这里遗漏了一些要点。首先,您需要清楚地标识要查找路径的元素/节点(对象)。
你没有在你的问题中概述你是如何做到这一点的,你只给出数组,然后给出字符串。
如果您的意思是对节点的引用并且想要获取它的路径,我在此答案中给出了一个例子。
首先,让我们引用对象(一般意义上)来获取路径:
// specify the node to search for
$node = &$array['marketplace']['browse request'][1];
由于 PHP 不允许识别字符串 - 并且您的数组可能多次包含相同的字符串 - 因此需要将此节点转换为可识别的对象。为了保留原始字符串值,它被存储到另一个变量中:
// make the node identifiable (so that it can be searched independent to it's string value, e.g. duplicates)
$string = "$node";
$node = new stdClass();
现在,您的原始数组具有要搜索的节点,以获取可识别的路径。print_r现在如下所示(缩短):
Array
(
[marketplace] => Array
(
[browse request] => Array
(
[0] => request type 1
[1] => stdClass Object
...
这是必要的,因为如果我们搜索数组并找到该对象,并且我们跟踪到目前为止在搜索中使用的路径,我们就获得了找到该对象的路径。
这正是我们现在在迭代器的帮助下所做的。PHP 已经知道如何遍历数组,并且在我们自己的一点帮助下,这甚至适用于包含对象的数组:
class MyRecursiveIterator extends RecursiveArrayIterator
{
public function hasChildren() {
return is_array($this->current());
}
}
将此RecursiveIterator
与 PHP 的标准树遍历RecursiveIteratorIterator
一起使用,我们可以生成路径,以防我们找到该对象:
$path = NULL;
$it = new RecursiveIteratorIterator(new MyRecursiveIterator($array));
foreach ($it as $value) {
if ($value !== $node) {
continue;
}
$path = [$string];
for ($count = $it->getDepth(); $count && $count--;) {
array_unshift($path, $it->getSubIterator($count)->key());
}
$path = implode(' -> ', $path);
break;
}
var_dump($path); # string(47) "marketplace -> browse request -> request type 2"
完整的示例代码一览(演示):
<?php
/**
* get path from child node to parent php array
* @link https://stackoverflow.com/a/18696550/367456
*/
class MyRecursiveIterator extends RecursiveArrayIterator
{
public function hasChildren()
{
return is_array($this->current());
}
}
$array = array(
'marketplace' => array(
'browse request' => array('request type 1', 'request type 2'),
'browse lab',
),
'marketplace2' => array('browse request2', 'browse lab2'),
'submitrequest' => array(''),
'aboutus' => array('')
);
// specify the node to search for
$node = & $array['marketplace']['browse request'][1];
// make the node identifiable (so that it can be searched independent to it's string value, e.g. duplicates)
$string = "$node";
$node = new stdClass();
$path = NULL;
$it = new RecursiveIteratorIterator(new MyRecursiveIterator($array));
foreach ($it as $value) {
if ($value !== $node) {
continue;
}
$path = [$string];
for ($count = $it->getDepth(); $count && $count--;) {
array_unshift($path, $it->getSubIterator($count)->key());
}
$path = implode(' -> ', $path);
break;
}
var_dump($path); # string(47) "marketplace -> browse request -> request type 2"