获取从子节点到父php数组的路径

时间:2022-05-25 13:38:56

I have an array like below, the size and element of array are not fixed its completely generated dynamicly

我有一个像下面这样的数组,数组的大小和元素没有固定它动态完全生成

array(
    'marketplace'   => array(
        'browse request' => array('request type 1', 'request type 2'),
        'browse lab',
    ),
    'marketplace2'  => array('browse request2', 'browse lab2'),
    'submitrequest' => array(''),
    'aboutus'       => array('')
)

I want to get the path from given child node to root node

我想从给定的子节点到根节点获取路径

Let us say for 'request type 2' then the path will be 'marketplace -> browse request -> request type 2'

让我们说'请求类型2'然后路径将是'市场 - >浏览请求 - >请求类型2'

and one more 'submitrequest' then the path will be 'submitrequest'

还有一个'submitrequest'然后路径将是'submitrequest'

Any help would be greatly appreciated. Thanks

任何帮助将不胜感激。谢谢

1 个解决方案

#1


0  

If your input is a unique string and therefore clearly identifiable, you can just compare the value (and as you added: the key as well) against the string and if found obtain the path:

如果您的输入是一个唯一的字符串,因此可以清楚地识别,您只需将该值(以及您添加的键:键)与字符串进行比较,如果找到,则获取路径:

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

Similar / Related Q&A:

相似/相关问答:


Earlier answer: You are probably missing some points here. First of all you need to clearly identify the element/node (object) you want to find the path to.

早些时候回答:你可能在这里遗漏了一些观点。首先,您需要清楚地标识要查找路径的元素/节点(对象)。

You have not outlined in your question how you do that, you only give the array and then the string.

你没有在你的问题中概述你是如何做到的,你只给出数组然后给出字符串。

If you mean to have a reference to the node and you want to get the path to it, I give an example how it works in this answer.

如果你的意思是对节点有一个引用,并且你想获得它的路径,我举一个例子说明它在这个答案中是如何工作的。

First of all, let's reference the object (in the general sense) to get the path from:

首先,让我们引用对象(在一般意义上)来获取路径:

// specify the node to search for
$node = &$array['marketplace']['browse request'][1];

As PHP does not allow to identify a string - and your array might contain the same string multiple times - this node needs to be turned into an object which is identifiable. To keep the original string value, it is stored into another variable:

由于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();

Now your original array has the node to be searched for to obtain the path from made identifiable. The print_r now looks as the following (shortened):

现在,您的原始数组具有要搜索的节点,以获取可识别的路径。 print_r现在看起来如下(缩短):

Array
(
    [marketplace] => Array
        (
            [browse request] => Array
                (
                    [0] => request type 1
                    [1] => stdClass Object
                    ...

This is necessary because if we search the array and find that object and we keep track of the path used so far in the search we have obtained the path when that object is found.

这是必要的,因为如果我们搜索数组并找到该对象并且我们跟踪到目前为止在搜索中使用的路径,我们已经获得了找到该对象时的路径。

And this is exactly what we do right now with the help of iterators. PHP already knows how to traverse an array and with a little help from ourselves, this even works with arrays containing objects:

这正是我们在迭代器的帮助下现在所做的。 PHP已经知道如何遍历数组并在我们自己的帮助下,这甚至适用于包含对象的数组:

class MyRecursiveIterator extends RecursiveArrayIterator
{
    public function hasChildren() {
        return is_array($this->current());
    }
}

Using this RecursiveIterator with PHP's standard tree traversal RecursiveIteratorIterator we can just generate the path in case we find that object:

使用这个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"

The full example code at a glance (Demo):

完整的示例代码一览(Demo):

<?php
/**
 * get path from child node to parent php array
 * @link https://*.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"

#1


0  

If your input is a unique string and therefore clearly identifiable, you can just compare the value (and as you added: the key as well) against the string and if found obtain the path:

如果您的输入是一个唯一的字符串,因此可以清楚地识别,您只需将该值(以及您添加的键:键)与字符串进行比较,如果找到,则获取路径:

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

Similar / Related Q&A:

相似/相关问答:


Earlier answer: You are probably missing some points here. First of all you need to clearly identify the element/node (object) you want to find the path to.

早些时候回答:你可能在这里遗漏了一些观点。首先,您需要清楚地标识要查找路径的元素/节点(对象)。

You have not outlined in your question how you do that, you only give the array and then the string.

你没有在你的问题中概述你是如何做到的,你只给出数组然后给出字符串。

If you mean to have a reference to the node and you want to get the path to it, I give an example how it works in this answer.

如果你的意思是对节点有一个引用,并且你想获得它的路径,我举一个例子说明它在这个答案中是如何工作的。

First of all, let's reference the object (in the general sense) to get the path from:

首先,让我们引用对象(在一般意义上)来获取路径:

// specify the node to search for
$node = &$array['marketplace']['browse request'][1];

As PHP does not allow to identify a string - and your array might contain the same string multiple times - this node needs to be turned into an object which is identifiable. To keep the original string value, it is stored into another variable:

由于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();

Now your original array has the node to be searched for to obtain the path from made identifiable. The print_r now looks as the following (shortened):

现在,您的原始数组具有要搜索的节点,以获取可识别的路径。 print_r现在看起来如下(缩短):

Array
(
    [marketplace] => Array
        (
            [browse request] => Array
                (
                    [0] => request type 1
                    [1] => stdClass Object
                    ...

This is necessary because if we search the array and find that object and we keep track of the path used so far in the search we have obtained the path when that object is found.

这是必要的,因为如果我们搜索数组并找到该对象并且我们跟踪到目前为止在搜索中使用的路径,我们已经获得了找到该对象时的路径。

And this is exactly what we do right now with the help of iterators. PHP already knows how to traverse an array and with a little help from ourselves, this even works with arrays containing objects:

这正是我们在迭代器的帮助下现在所做的。 PHP已经知道如何遍历数组并在我们自己的帮助下,这甚至适用于包含对象的数组:

class MyRecursiveIterator extends RecursiveArrayIterator
{
    public function hasChildren() {
        return is_array($this->current());
    }
}

Using this RecursiveIterator with PHP's standard tree traversal RecursiveIteratorIterator we can just generate the path in case we find that object:

使用这个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"

The full example code at a glance (Demo):

完整的示例代码一览(Demo):

<?php
/**
 * get path from child node to parent php array
 * @link https://*.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"