up vote 1 down vote favorite
1

Hi,

  • What I want, is a function that searches through my array, and returns all the children to a specific node. What is the most appropriate way to do this? Will recursion be necessary in this case?

I have previously constructed a few quite complex functions that iterates with or without the help of recursion through multi-dimensional arrays and re-arranging them but this problem makes me completely stuck and I can't just get my head around it...

Here's my array:

Array
(
    [1] => Array (
            [id] => 1
            [parent] => 0

        )

    [2] => Array (
            [id] => 2
            [parent] => 1
        )

    [3] => Array (
            [id] => 3
            [parent] => 2
        )   
)

Thanks a lot,

UPDATE:
The output which I want to get. Sorry for the bad example, but I'll blame it on lack of knowledge on how to format the stuff I need to do :)

function getAllChildren($id) {
    // Psuedocode
    return $array;
}

getAllChildren(1); // Outputs the following:

Array
(   
    [2] => Array (
            [id] => 2
            [parent] => 1
        )

    [3] => Array (
            [id] => 3
            [parent] => 2
        )   
)
flag

3 Answers

up vote 4 down vote accepted
$nodes = array( 1   => array (  'id'        => 1,
                                'parent'    => 0
                             ),
                2   => array ( 'id'         => 2,
                               'parent'     => 1
                             ),
                3   => array ( 'id'         => 3,
                               'parent'     => 2
                             )
                );


function searchItem($needle,$haystack) {
    $nodes = array();
    foreach ($haystack as $key => $item) {
        if ($item['parent'] == $needle) {
            $nodes[$key] = $item;
            $nodes = $nodes + searchItem($item['id'],$haystack);
        }
    }
    return $nodes;
}


$result = searchItem('1',$nodes);
echo '<pre>';
var_dump($result);
echo '</pre>';

Non-recursive version of the searchItem() function:

function searchItem($needle,$haystack) {
    $nodes = array();
    foreach ($haystack as $key => $item) {
        if (($item['parent'] == $needle) || array_key_exists($item['parent'],$nodes)) {
            $nodes[$key] = $item;
        }
    }
    return $nodes;
}

(assumes ordering of the parents/children, so a child node isn't included in the array unless the parent is already there)

link|flag
Hi mark! Thanks for your help! How would you modify it to be able to deal with finding multi-level children's? – Industrial Jun 22 at 12:49
To explain, if I run the function on the array in my example on the top node, I want to have both node 2&3 returned, since they both children to the top node, but on multiple levels. – Industrial Jun 22 at 12:50
Hi Mark, Thanks a lot for your update. It works like a charm! – Industrial Jun 22 at 13:06
1  
It produces the same results as the first (recursive) function using the same initial array as shown in my code, but won't return the correct results if a child is defined in the array before its parent – Mark Baker Jun 22 at 14:23
1  
@Industrial I've removed my post. While you can do it with SPL, it does overcomplicate things for your UseCase. Mark's solution is fine. Keep it Simple. – Gordon Jun 22 at 15:14
show 2 more comments
up vote 1 down vote
<?php
function searchItem($needle)
{
    foreach ($data as $key => $item)
    {
        if ($item['id'] == $needle)
        {
            return $key;
        }
    }
    return null;
}
?>
link|flag
Hi, thanks! Im afraid that you misunderstood me though. I need the children nodes to a specific "id" – Industrial Jun 22 at 12:41
1  
I don't understand. Can you supply an example? – Sjoerd Jun 22 at 12:52
Updated original post. Thanks for your interest :) – Industrial Jun 22 at 13:07
up vote 1 down vote

Check out the array_walk_recursive() function in PHP:

http://www.php.net/manual/en/function.array-walk-recursive.php

link|flag

Your Answer

get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.