Recursive functions and multidimensional arrays

How can i get the ['id'] from all children elements if i pass it an id.

This is my array...

$array = Array
(
    '0' => Array
    (
        'id' => 1,
        'parent_id' => 0,
        'order_pos' => 0,
        'title' => 'Shirts',
        'childs' => Array
        (
            '0' => Array
            (
                'id' => 2,
                'parent_id' => 1,
                'order_pos' => 0,
                'title' => 'Small Shirts',
            )
        )
    ),
    '1' => Array
    (
        'id' => 3,
        'parent_id' => 0,
        'order_pos' => 0,
        'title' => 'Cameras'
    )
);

If i write i function and pass a variable of say id 1 can someone please tell me how i can return a single dimensional array with merely just the id's of all child elements.. For instance.

From the previous array, if i pass the id of 1, i want the function to return 1, 2 as 2 is an id element of a child element. So if i pass it 2, it should only return 2 as it doesnt have any children.

I hope you understand me, thank you if you can help me...

Note, this can be unlimited, meaning each parent category can have unlimited sub categories or children.


There is basically two problems you need to solve:

  • search the entire array for the given ID to start at.
  • pluck all the IDs from the children once the ID is found.
  • This would work:

    function findIds(array $array, $id)
    {
        $ids = array();
        $iterator = new RecursiveIteratorIterator(
            new RecursiveArrayIterator($array),
            RecursiveIteratorIterator::SELF_FIRST
        );
    
        foreach ($iterator as $val) {
            if (is_array($val) && isset($val['id']) && $val['id'] === $id) {
                $ids[] = $val['id'];
                if (isset($val['childs'])) {
                    array_walk_recursive(
                        $val['childs'],
                        function($val, $key) use (&$ids) {
                            if ($key === 'id') {
                                $ids[] = $val;
                            }
                        }
                    );
                }
            }
        }
    
        return $ids;
    }
    
    print_r( findIds($array, 1) ); // [1, 2]
    print_r( findIds($array, 2) ); // [2]
    print_r( findIds($array, 3) ); // [3]
    

    The Iterators will make your array fully traversable. This means, you can foreach over the entire array like it was a flat one. Normally, it would return only the leaves (1, 0, 0, Shirts, …), but since we gave it the SELF_FIRST option it will also return the arrays holding the leaves. Try putting a var_dump inside the foreach to see.

    In other words, this

    foreach ($iterator as $val) {
    

    will go over each and every value in the array.

    if (is_array($val) && isset($val['id']) && $val['id'] === $id) {
    

    This line will only consider the arrays and check for the ID you passed to the findById function. If it exists, the ID is added to the array that will get returned by the function. So that will solve problem 1: finding where to start.

    if (isset($val['childs'])) { 
    

    If the array has an item "childs" (it should be children btw), it will recursively fetch all the IDs from that item and add them to the returned array:

    array_walk_recursive(
        $val['childs'],
        function($val, $key) use (&$ids) {
            if ($key === 'id') {
                $ids[] = $val;
            }
        }
    );
    

    The array_walk_recursive accepts an array (1st argument) and will pass the value and the key of the leaves to the callback function (2nd argument). The callback function merely checks if the leaf is an ID value and then add it to the return array. As you can see, we are using a reference to the return array. That is because using use ($ids) would create a copy of the array in the closure scope while we want the real array in order to add items to it. And that would solve problem 2: adding all the child IDs.

    链接地址: http://www.djcxy.com/p/58604.html

    上一篇: 为什么我在PHP中的SQL查询失败?

    下一篇: 递归函数和多维数组