# When to use recursion?
There are cases where recursion is the simplest solution. Especially, in those cases where the data has the form of a tree with an unknown number of splits. For example, when performing operations on HTML where each node can have an unknown number of sub-nodes, or when working with XML or JSON.
The following example is of a JSON which contains items representing animal groups:
$animals = '{"animals":[
{"name":"apes","parent":"mammals","link":"//animals.com/mammals/apes"},
{"name":"fishes","parent":"animals","link":"//animals.com/fishes"},
{"name":"animals","parent":"kingdom","link":"//animals.com"},
{"name":"mammals","parent":"animals","link":"//animals.com/mammals"},
{"name":"marsupials","parent":"mammals","link":"//animals.com/mammals/marsupials"},
{"name":"opossums","parent":"marsupials","link":"//animals.com/mammals/marsupials/opossums"},
{"name":"big apes","parent":"apes","link":"//animals.com/mammals/big-apes"},
{"name":"birds","parent":"animals","link":"//animals.com/birds"},
{"name":"cats","parent":"mammals","link":"//animals.com/mammals/cats"},
{"name":"big cats","parent":"cats","link":"//animals.com/mammals/cats/big-cats"},
{"name":"domestic cats","parent":"cats","link":"//animals.com/mammals/cats/domestic-cats"},
{"name":"persian cats","parent":"domestic cats","link":"//animals.com/mammals/cats/domestic-cats/persian-cats"},
{"name":"chimpanzee","parent":"big apes","link":"//animals.com/mammals/big-apes/chimpanzee"}
]}';
Each JSON item represents:
- The name of the group (E.g. chimpanzee)
- The name of the family to which the group belongs (E.g. apes)
- Link to an imaginary website which contains data about the item.
Our goal is to arrange the items in hierarchical order where the group of mammals is below the group of animals and above the group of apes, etc then display the result as menu items that preserve the order.
This is how it should look when we are done, a list containing several levels of sub-lists the number of which we do not know in advance:
A possible solution is to use two functions. The first, a recursive function, arranges the messy JSON in a hierarchical order. The second builds the links in the menu.
The name of the first recursive function is makeTree. It receives a multidimensional array and arranges it in a hierarchical order:
function makeTree($arr=[], $branch="")
{
$tree=[];
foreach($arr as $item) {
if($item["parent"] === $branch) {
$item["children"] = makeTree($arr,$item["name"]);
$tree[$branch][] = $item;
}
}
return $tree;
}
- The function receives two arguments:
- $arr - the array that the function needs to put in order
- $branch - the name of the branch that the function needs to find its immediate children (the items below it in the hierarchy)
- The function builds a multidimensional array, $tree, that includes all the children in a particular step.
- The function runs on the list of items in the array it receives ($arr) until it finds an item whose parent is the same as $branch.
- For the item that the function finds it searches for the it's children by further calling itself with the name of the current branch. A function that calls itself as long as a certain condition is met is a recursive function.
- Each of the children that the function finds is added to the multidimensional array $tree that the function generates in the process.
- Where is the stopping condition? The function calls itself only if an item has children.
The second function, makeNav, accepts as a parameter the ordered array that comes from the makeTree function then builds the HTML structure of a nested list (list within list):
function makeNav($arr=[])
{
$nav='<ul>';
foreach($arr as $key => $val) {
if($val["children"] && count($val["children"]) > 0) {
$nav .= '<li>';
$nav .= "<a href="{$val['link']}">{$val['name']}</a>";
$nav .= '<ul>';
foreach($val["children"] as $item) {
$nav .= makeNav($item);
}
$nav .= '</ul>';
$nav .= '</li>';
} else {
$nav .= '<li>';
$nav .= "<a href="{$val['link']}">{$val['name']}</a>";
$nav .= '</li>';
}
}
$nav .= '</ul>';
return $nav;
}
To generate the hierarchy, we call the makeTree recursive function. We then pass the result to the makeNav function to build the HTML structure:
$rootName = "kingdom";
$animalsArray = json_decode($animals, true);
$tree = makeTree($animalsArray["animals"], $rootName);
$nav = makeNav($tree[$rootName]);
echo $nav;
The result: