Andris
Andris

Reputation: 1442

From php multidimensional array trying to create nested ul li menu (unlimited nested levels)

Here is what i have got http://codepad.org/iDoXXsLX

Have array like this

Array
(
[0] => Array
    (
        [NumberRenamed] => 17
        [TopicName] => Products
        [UpperLevelNumberRenamed] => 0
    )

[17] => Array
    (
        [0] => Array
            (
                [1] => Array
                    (
                        [NumberRenamed] => 18
                        [TopicName] => Computers
                        [UpperLevelNumberRenamed] => 17
                    )
            )
    )

[18] => Array
    (
        [0] => Array
            (
                [2] => Array
                    (
                        [NumberRenamed] => 16
                        [TopicName] => Laptops
                        [UpperLevelNumberRenamed] => 18
                    )
            )
    )

[16] => Array
    (
        [0] => Array
            (
                [4] => Array
                    (
                        [NumberRenamed] => 8
                        [TopicName] => Dell
                        [UpperLevelNumberRenamed] => 16
                    )
            )
    )
)

Top level item is Products, first sub-level item is Computers, next sub-level is Laptops, then again next sub-level Dell

For each sub-level item UpperLevelNumberRenamed == to closest upper level NumberRenamed.

Want to get result like this

Products
  Computers
    Laptops
      Dell
      Acer
    Desktops
Home

Tried this

foreach( $main_topics as $k_main_topics => $v_main_topics ){

if( isset($v_main_topics['UpperLevelNumberRenamed']) and $v_main_topics['UpperLevelNumberRenamed'] == 0 ){
//print only top level topics
echo $v_main_topics['TopicName']. '<br/>';
}

else{//if not top level topic

foreach( $v_main_topics[0] as $k_v_main_topics_0 => $v_v_main_topics_0 ){
echo $v_v_main_topics_0['TopicName']. '<br/>';
}//foreach( $v_main_topics[0] as $k_v_main_topics_0 => $v_v_main_topics_0 )

}//else{

}//foreach( $main_topics as $k_main_topics => $v_main_topics )

But get this

Products
Home
Computers
Laptops
Desktops
Dell
Acer

Something incorrect, but can not understand what. Please, advice what need to correct/change in the code

Trying another way

Initial array is one dimensional array. Trying to get ul li navigation from one dimensional.

Here is what i did http://codepad.org/OLtxyL4X

Upvotes: 5

Views: 1462

Answers (2)

Dave Chen
Dave Chen

Reputation: 10975

Here's a summary of what it does:

  • flatten the array recursively
  • build a multi-dimensional relation map
  • create 1D relationships that link UpperLevelNumberRenamed to NumberRenamed
  • print out the multi-dimensional as an ul-li list.

Here it is:

$flat = array();
foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($main_topics)) as $i)
  $flat[] = $i;
$final = array();
$defs = array();
for ($i = 0; $i < count($flat); $i += 3)
    if ($flat[$i + 2] == 0) {
        $final[$flat[$i + 1]] = array();
        $defs[$flat[$i]] = &$final[$flat[$i + 1]];
    } else {
        $defs[$flat[$i + 2]][$flat[$i + 1]] = array();
        $defs[$flat[$i]] = &$defs[$flat[$i + 2]][$flat[$i + 1]];
    }

function array2ul($array) {
    $out = "<ul>";
    foreach($array as $key => $elem)
        $out = is_array($elem) ?
        $out . "<li><span>$key</span>" . array2ul($elem) . "</li>" : 
        $out = $out."<li><span>$key:[$elem]</span></li>";
    $out = $out . "</ul>";
    return $out; 
}

echo array2ul($final);

Output:

<ul><li><span>Products</span><ul><li><span>Computers</span><ul><li><span>Laptops</span><ul><li><span>Dell</span><ul></ul></li><li><span>Acer</span><ul></ul></li></ul></li><li><span>Desktops</span><ul></ul></li></ul></li></ul></li><li><span>Home</span><ul></ul></li></ul>

Upvotes: 4

KAD
KAD

Reputation: 11102

This shall be a working example using recursion, not tested though:

Define the array

 $main_array = Array
    (
        '10' => Array
        (
            'name' => 'Products'
            'children' => Array
            (
                '12' => Array
                (
                    'name' => 'Laptop',
                    'children' => Array
                    (

                        '13' => Array
                        (
                            'name' => 'Dell',
                        ),
                        '14' => Array
                        (               
                            'name' => 'Acer',
                        )
                    )
                )
                '14' => Array
                (
                    'name' => 'Desktop',
                    'children' => Array
                    (

                        '15' => Array
                        (
                            'name' => 'Sony',
                        ),
                        '16' => Array
                        (               
                            'name' => 'Apple',
                        )
                    )
                ),
            ) 

        )
    )

Create and call the function :

 function createList($main_topics)
        {
            if($main_topics == null || sizeof($main_topics) <= 0)
            {
                return '';
            }

            $list = '<ul>';
            foreach($main_topics as $k_main_topics => $v_main_topics )
            {

                $list .= '<li id="' . $k_main_topics'"> '. $v_main_topics['name'] . ' ' .  createList(isset($v_main_topics["children"]) ? $v_main_topics["children"] : null) . '</li>' ;

            }

            $list .= '</ul>';

            return $list;

        }

        echo createList($main_array);

Upvotes: 1

Related Questions