0

I have the following array :

Array
(
    [0] => Array
        (
            [ID] => 1
            [PARENT] => 0
            [NAME] => Your first category
        )
    [1] => Array
        (
            [ID] => 2
            [PARENT] => 1
            [NAME] => Your first forum
        )
    [2] => Array
        (
            [ID] => 4
            [PARENT] => 1
            [NAME] => Another Forum
        )
    [3] => Array
        (
            [ID] => 5
            [PARENT] => 1
            [NAME] => Good Forum
        )
    [4] => Array
        (
            [ID] => 6
            [PARENT] => 0
            [NAME] => Top Forum
        )
    [5] => Array
        (
            [ID] => 7
            [PARENT] => 6
            [NAME] => Sub Forum #1
        )
    [6] => Array
        (
            [ID] => 9
            [PARENT] => 7
            [NAME] => Sub Forum #1-1
        )
    [7] => Array
        (
            [ID] => 10
            [PARENT] => 7
            [NAME] => Sub Forum #1-2
        )
    [8] => Array
        (
            [ID] => 8
            [PARENT] => 6
            [NAME] => Sub Forum #2
        )
)

OK Here I have the var_export result as requested :

array (
  0 => 
  array (
    'ID' => '1',
    'PARENT' => '0',
    'NAME' => 'Your first category',
  ),
  1 => 
  array (
    'ID' => '2',
    'PARENT' => '1',
    'NAME' => 'Your first forum',
  ),
  2 => 
  array (
    'ID' => '4',
    'PARENT' => '1',
    'NAME' => 'Another Forum',
  ),
  3 => 
  array (
    'ID' => '5',
    'PARENT' => '1',
    'NAME' => 'Good Forum',
  ),
  4 => 
  array (
    'ID' => '6',
    'PARENT' => '0',
    'NAME' => 'Top Forum',
  ),
  5 => 
  array (
    'ID' => '7',
    'PARENT' => '6',
    'NAME' => 'Sub Forum #1',
  ),
  6 => 
  array (
    'ID' => '9',
    'PARENT' => '7',
    'NAME' => 'Sub Forum #1-1',
  ),
  7 => 
  array (
    'ID' => '10',
    'PARENT' => '7',
    'NAME' => 'Sub Forum #1-2',
  ),
  8 => 
  array (
    'ID' => '8',
    'PARENT' => '6',
    'NAME' => 'Sub Forum #2',
  ),
)

Some of that arrays PARENT value corespond to another array ID value. That helps me to make them nested. But the question is: how can I create an HTML list that will look like that:

<ul>
    <li id="1">
        Your First Category
        <ul>
            <li id="2">
                Your First Forum
            </li>
            <li id="4">
                Another Forum
            </li>
            <li id="5">
                Good Forum
            </li>
        <ul>
    </li>
    <li id="6">
        Top Forum
        <ul>
            <li id="7">
                Sub Forum #1
                <ul>
                    <li id="9">
                        Sub Forum #1-1
                    </li>
                    <li id="10">
                        Sub Forum #1-2
                    </li>
                </ul>
            </li>
            <li id="7">
                Sub Forum #2
            </li>
        <ul>
    </li>
</ul>

Any idea please?

KodeFor.Me
  • 13,069
  • 27
  • 98
  • 166
  • 1
    It would be so much easier, if you gave output `var_export()` instead of `print_r()`... – binaryLV Oct 06 '11 at 08:39
  • 1
    I'd rather convert the array to a proper nested form before converting it as HTML list. – LeleDumbo Oct 06 '11 at 08:46
  • This is what I need ! To change the array form in order to meed the HTML Layout in a later actions. I just display the HTML in order to show the form of the array that I need. – KodeFor.Me Oct 06 '11 at 08:47
  • 1
    Instead of letting php number your array, use the ID column as the array key. Then getting a parent is a trivial array lookup. You will have to watch out for a recursive array where a parent of a parent is the child. – Ariel Oct 06 '11 at 08:49
  • Can you please show me exactly what you mean ? It looks like a good idea but I have not get it at all ! :? – KodeFor.Me Oct 06 '11 at 08:51
  • @MerianosNikos, you don't really need an array with the same layout as HTML. It's enough with `$data[$parentID] = array($child, $child, ...)` structure. Then, loop through `$data[0]` (top level), for each element from `$data[0]` loop through `$data[$item['id']]` etc. See my answer below, there's an example. – binaryLV Oct 06 '11 at 08:56

2 Answers2

7

What I would do:

  1. group menu(?) items by their parent id - $menu[$parentID] = array($child, $child, ...)
  2. use recursive function for generating menu for each parent - makeMenu($menu, $parentID)

This will allow you to visit each node twice - first time, when reordering array, second time, when printing node. So it will work great with small as well as with large arrays.

Source:

$data = array(
    0 => array(
        'ID'     => '1',
        'PARENT' => '0',
        'NAME'   => 'Your first category',
    ),
    1 => array(
        'ID'     => '2',
        'PARENT' => '1',
        'NAME'   => 'Your first forum',
    ),
    2 => array(
        'ID'     => '4',
        'PARENT' => '1',
        'NAME'   => 'Another Forum',
    ),
    3 => array(
        'ID'     => '5',
        'PARENT' => '1',
        'NAME'   => 'Good Forum',
    ),
    4 => array(
        'ID'     => '6',
        'PARENT' => '0',
        'NAME'   => 'Top Forum',
    ),
    5 => array(
        'ID'     => '7',
        'PARENT' => '6',
        'NAME'   => 'Sub Forum #1',
    ),
    6 => array(
        'ID'     => '9',
        'PARENT' => '7',
        'NAME'   => 'Sub Forum #1-1',
    ),
    7 => array(
        'ID'     => '10',
        'PARENT' => '7',
        'NAME'   => 'Sub Forum #1-2',
    ),
    8 => array(
        'ID'     => '8',
        'PARENT' => '6',
        'NAME'   => 'Sub Forum #2',
    ),
);

// reorder array
$menu = array();
foreach ( $data as $item ) {
    $menu[$item['PARENT']][] = $item;
}

// print menu
function makeMenu($menu, $parentID) {
    $html = "<ul>";
    foreach ( $menu[$parentID] as $item ) {
        $html .= "<li id='{$item['ID']}'>{$item['NAME']}";
        if ( isset($menu[$item['ID']]) ) {
            $html .= makeMenu($menu, $item['ID']);
        }
        $html .= "</li>";
    }
    $html .= "</ul>";
    return $html;
}
echo makeMenu($menu, 0);

Output (added spacings manually):

<ul>
    <li id='1'>
        Your first category
        <ul>
            <li id='2'>Your first forum</li>
            <li id='4'>Another Forum</li>
            <li id='5'>Good Forum</li>
        </ul>
    </li>
    <li id='6'>
        Top Forum
        <ul>
            <li id='7'>Sub Forum #1
                <ul>
                    <li id='9'>Sub Forum #1-1</li>
                    <li id='10'>Sub Forum #1-2</li>
                </ul>
            </li>
            <li id='8'>Sub Forum #2</li>
        </ul>
    </li>
</ul>
binaryLV
  • 9,002
  • 2
  • 40
  • 42
1
$new_arr = array();
foreach($arr as $data) $new_arr[$data['id']] = $data;

foreach($new_arr as $id => &$data) $data['parent'] =& $new_arr[$data['parent']];

Now you have a proper array structure.

But you may have to turn it inside out, since it's structured by child. But your output is by parent.

So instead of the second foreach I posted, do this:

foreach($new_arr as $id => $data) $new_arr[$data['parent']]['children'][] =& $data;
Ariel
  • 25,995
  • 5
  • 59
  • 69