Converting a nested array to an HTML nested list?

How should one convert an array of nested elements into a nested list?

For instance say you had an array like:

$array = array("Apple"=>array(), "Banana"=>array(), "Tangerine"=>array("Pear"=>array("Walnut"=>array(), "Ice Cream"=>array(), "Candy"=>array()), "Nectar"=>array()), "Honey"=>array(), "Sweets"=>array());

Array
(
    [Apple] => Array
        (
        )
    [Banana] => Array
        (
        )
    [Tangerine] => Array
        (
            [Pear] => Array
                (
                    [Walnut] => Array
                        (
                        )
                    [Ice Cream] => Array
                        (
                        )
                    [Candy] => Array
                        (
                        )
                )
            [Nectar] => Array
                (
                )
        )
    [Honey] => Array
        (
        )
    [Sweets] => Array
        (
        )
)

And wanted to convert that into a nested list like:

<ul>
	<li>Apple</li>
	<li>Banana</li>
	<li>Tangerine
		<ul>
			<li>Pear
				<ul>
					<li>Walnut</li>
					<li>Ice Cream</li>
					<li>Candy</li>
				</ul>
			</li>
			<li>Nectar</li>
		</ul>
	</li>
	<li>Honey</li>
	<li>Sweets</li>
</ul>

This is a situation where you would want to use recursion:

<?php
	//Make a list from an array
	function makeList($array) {

		//Base case: an empty array produces no list
		if (empty($array)) return '';

		//Recursive Step: make a list with child lists
		$output = '<ul>';
		foreach ($array as $key => $subArray) {
			$output .= '<li>' . $key . makeList($subArray) . '</li>';
		}
		$output .= '</ul>';
		
		return $output;
	}

	$array = array("Apple"=>array(), "Banana"=>array(), "Tangerine"=>array("Pear"=>array("Walnut"=>array(), "Ice Cream"=>array(), "Candy"=>array()), "Nectar"=>array()), "Honey"=>array(), "Sweets"=>array());
	echo makeList($array);
?>

Outputs:

<ul><li>Apple</li><li>Banana</li><li>Tangerine<ul><li>Pear<ul><li>Walnut</li><li>Ice Cream</li><li>Candy</li></ul></li><li>Nectar</li></ul></li><li>Honey</li><li>Sweets</li></ul>

Displays as:

  • Apple
  • Banana
  • Tangerine
    [list]
  • Pear
    [list]
  • Walnut
  • Ice Cream
  • Candy
    [/list]
  • Nectar
    [/list]
  • Honey
  • Sweets

Thank you very much :slight_smile:

I made some modifications that alter the formatting of the output with added whitespace, and also allows you to optionally pass in an array containing alternate keys (so you can for instance replace numeric ID’s with names):

function makeList($array, $depth=0, $key_map=FALSE) {
	$whitespace = str_repeat("\	", $depth*2);
	//Base case: an empty array produces no list
	if (empty($array)) return '';
	//Recursive Step: make a list with child lists
	$output = "$whitespace<ul>\
";
	foreach ($array as $key => $subArray) {
		$subList = makeList($subArray, $depth+1, $key_map);
		if($key_map AND $key_map[$key]) $key = $key_map[$key];
		if($subList) $output .= "$whitespace\	<li>" . $key . "\
" . $subList . "$whitespace\	</li>\
";
		else $output .= "$whitespace\	<li>" . $key . $subList . "</li>\
";
	}
	$output .= "$whitespace</ul>\
";
	return $output;
}

What about if you had to create nested list from such array:


'categories' => array(
'1' => array('id' => 1,	'parentid' => 0, 'title' => 'Category 1', 'url' => 'url-1'),
'2' => array('id' => 2, 'parentid' => 0, 'title' => 'Category 2', 'url' => 'url-2'),

'3' => array('id' => 3,	'parentid' => 1, 'title' => 'Category 3', 'url' => 'url-3'),
'4' => array('id' => 4, 'parentid' => 1, 'title' => 'Category 4', 'url' => 'url-4'),

'5' => array('id' => 5,	'parentid' => 3, 'title' => 'Category 5', 'url' => 'url-5'),
'6' => array('id' => 6, 'parentid' => 3, 'title' => 'Category 6', 'url' => 'url-6'),
);


And the result ul list to contain list’s with the link:

<li><a href=“url”> title</a></li>

Novice here, please help :goof:

You’d have to convert that array to the format the makeList() function accepts. Make it a nested array, with the $key_map array containing the anchor text. e.g. $key_map = array(‘1’=>‘<a href=“url-1”>Category 1</a>’, …)