cnkt Posted May 25, 2009 Share Posted May 25, 2009 i have got a array like this: $a = array( array('title' => 'ROOT 1', 'depth' => '0'), array('title' => 'CHILD 1 OF ROOT 1', 'depth' => '1'), array('title' => 'CHILD 2 OF ROOT 1', 'depth' => '1'), array('title' => 'CHILD 1 OF CHILD 2', 'depth' => '2'), array('title' => 'ROOT 2', 'depth' => '0'), ); when i output this array with this function: function generateList($arr) { echo '<ul>'; foreach ($arr as $item) { echo '<li>' . str_repeat('-', $item['depth']) . $item['title'] . '</li>'; } echo '</ul>'; } i get this: ROOT 1 -CHILD 1 OF ROOT 1 -CHILD 2 OF ROOT 1 --CHILD 1 OF CHILD 2 ROOT 2 but what i want is a nested XHTML valid UL LI like: <ul> <li>ROOT 1 <ul> <li>CHILD 1 OF ROOT 1</li> </ul> </li> </ul> thanks. Quote Link to comment https://forums.phpfreaks.com/topic/159557-array-to-ul-li-list/ Share on other sites More sharing options...
GingerRobot Posted May 25, 2009 Share Posted May 25, 2009 I think you're going to struggle with this using an array in the way you are -- you need to store the relationship between the child node and the parent node. For things like this, i usually store the parent node as the key of the array, the value of which is all the children. Something like this: $array['root'] = array('ROOT1','ROOT2'); $array['ROOT1'] = array('CHILD 1 OF ROOT 1','CHILD 2 OF ROOT 1'); $array['CHILD 2 OF ROOT 1'] = array('CHILD 1 OF CHILD 2'); Then, you can use a recursive function like so: function listElements($array,$index='root'){ echo '<ul>'; foreach($array[$index] as $item){ echo '<li>'; echo $item; if(isset($array[$item])){ listElements($array,$item); } echo '</li>'; } echo '</ul>'; } listElements($array); Also, by doing this in a recursive manner, you don't limit yourself with regard to the depth of the list. Quote Link to comment https://forums.phpfreaks.com/topic/159557-array-to-ul-li-list/#findComment-841664 Share on other sites More sharing options...
ToonMariner Posted May 25, 2009 Share Posted May 25, 2009 would it not be more beneficial to store children as an array under the parent node? something like <?php $a = array( array('title' => 'ROOT 1', 'children' => array( array('title' => 'CHILD 1 OF ROOT 1', 'children' => NULL), array('title' => 'CHILD 2 OF ROOT 1', 'children' => array( array('title' => 'CHILD 1 OF CHILD 2', 'children' => NULL) ) ) array('title' => 'ROOT 2', 'children' => NULL), ); ?> can then use a recursive function to spit out the nested list Quote Link to comment https://forums.phpfreaks.com/topic/159557-array-to-ul-li-list/#findComment-841695 Share on other sites More sharing options...
GingerRobot Posted May 25, 2009 Share Posted May 25, 2009 would it not be more beneficial to store children as an array under the parent node? Quite possibly. It would certainly be more representative of the actual data. It's just, depending on how you store your data, it might be easier to produce my representation of the data rather than yours. If, for example, we just store the parent node alongside the child node in a database, it would be very easy to select all the rows once and run through it producing my array. Unless im missing something simple, i think it'd be more difficult to work out where each row belongs in your array. On the other hand, i suspect your representation would be easier to search and would consume less memory, since we're only passing part of the array into the recursive function each time we call it. Quote Link to comment https://forums.phpfreaks.com/topic/159557-array-to-ul-li-list/#findComment-841699 Share on other sites More sharing options...
cnkt Posted May 25, 2009 Author Share Posted May 25, 2009 I'm sorry but the array is not creating by me. We are a team and i'm only responsible of the VIEW part of project. I can't say to developer "give me a nested array". i have to do the UL LI with the DEPTH field of array. Quote Link to comment https://forums.phpfreaks.com/topic/159557-array-to-ul-li-list/#findComment-841704 Share on other sites More sharing options...
GingerRobot Posted May 25, 2009 Share Posted May 25, 2009 I'm sorry but the array is not creating by me. We are a team and i'm only responsible of the VIEW part of project. I can't say to developer "give me a nested array". i have to do the UL LI with the DEPTH field of array. I don't see how that's possible. For example. If i tell you a particular element has a depth of 2, can you tell me which parent it has? Sure you can tell me it's parent has a depth of 1, but you can't tell me which parent it belongs to. Unless of course the ordering is guaranteed such that if the depth increases you know that the child belongs to the most recent node with a depth one less than it. Quote Link to comment https://forums.phpfreaks.com/topic/159557-array-to-ul-li-list/#findComment-841708 Share on other sites More sharing options...
Daniel0 Posted May 25, 2009 Share Posted May 25, 2009 Hmm... $a = array( array('title' => 'ROOT 1', 'depth' => '0'), array('title' => 'CHILD 1 OF ROOT 1', 'depth' => '1'), array('title' => 'CHILD 2 OF ROOT 1', 'depth' => '1'), array('title' => 'CHILD 1 OF CHILD 2', 'depth' => '2'), array('title' => 'ROOT 2', 'depth' => '0'), ); $prevDepth = null; foreach ($a as $element) { if (null === $prevDepth || $element['depth'] > $prevDepth) { echo '<ul>'; } else if ($element['depth'] == $prevDepth) { echo '</li>'; } else if ($element['depth'] < $prevDepth) { echo str_repeat('</li></ul>', $prevDepth - $element['depth']) . '</li>'; } echo "<li>{$element['title']}"; $prevDepth = (int) $element['depth']; } echo str_repeat('</li></ul>', $prevDepth+1); Output: <ul><li>ROOT 1<ul><li>CHILD 1 OF ROOT 1</li><li>CHILD 2 OF ROOT 1<ul><li>CHILD 1 OF CHILD 2</li></ul></li></ul></li><li>ROOT 2</li></ul> which is valid (X)HTML. Quote Link to comment https://forums.phpfreaks.com/topic/159557-array-to-ul-li-list/#findComment-841731 Share on other sites More sharing options...
cnkt Posted May 26, 2009 Author Share Posted May 26, 2009 Hmm... $a = array( array('title' => 'ROOT 1', 'depth' => '0'), array('title' => 'CHILD 1 OF ROOT 1', 'depth' => '1'), array('title' => 'CHILD 2 OF ROOT 1', 'depth' => '1'), array('title' => 'CHILD 1 OF CHILD 2', 'depth' => '2'), array('title' => 'ROOT 2', 'depth' => '0'), ); $prevDepth = null; foreach ($a as $element) { if (null === $prevDepth || $element['depth'] > $prevDepth) { echo '<ul>'; } else if ($element['depth'] == $prevDepth) { echo '</li>'; } else if ($element['depth'] < $prevDepth) { echo str_repeat('</li></ul>', $prevDepth - $element['depth']) . '</li>'; } echo "<li>{$element['title']}"; $prevDepth = (int) $element['depth']; } echo str_repeat('</li></ul>', $prevDepth+1); Output: <ul><li>ROOT 1<ul><li>CHILD 1 OF ROOT 1</li><li>CHILD 2 OF ROOT 1<ul><li>CHILD 1 OF CHILD 2</li></ul></li></ul></li><li>ROOT 2</li></ul> which is valid (X)HTML. thanks. your method works. Quote Link to comment https://forums.phpfreaks.com/topic/159557-array-to-ul-li-list/#findComment-842188 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.