JsusSalv Posted August 8, 2009 Share Posted August 8, 2009 Hello: I have several nested foreach loops like so: foreach($this1 as $that1) { //extract info, etc... foreach($this2 as $that2) { //extract info, etc... foreach($this3 as $that3) { //extract info, etc... foreach($this4 as $that4) { //extract info, etc... foreach($this5 as $that5) { //extract info, etc... } } } } } This is a monster. Is there a way to write a 'for' loop that can iterate through as many nested foreach loops as needed? I don't mind creating a bunch of these foreach loops but somehow I feel that there is a better way. My main priority is to keep the nested order. Thank you! Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/ Share on other sites More sharing options...
gevans Posted August 8, 2009 Share Posted August 8, 2009 Can you show the array(s) your looping through, will be easier to understand Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-893579 Share on other sites More sharing options...
JsusSalv Posted August 8, 2009 Author Share Posted August 8, 2009 Can you show the array(s) your looping through, will be easier to understand Good point! I'm actually pulling info from a database via two classes. $containers = DISPLAY::displayParentElements($blah); $subcontainers = DISPLAY::displayChildElements($blah); I then place the resultsets into foreach loops: foreach($containers as $parent) { //extract info, etc... $parentDiv = $parent['parentDiv']; echo '<div id="'.$parentDiv.'">'; foreach($subcontainers as $child) { //extract info, etc... $childDiv = $child['childDiv']; echo '<div id="'.$childDiv.'">'; foreach($subcontainers as $grandChild) { //extract info, etc... $grandChildDiv = $grandChild['grandChildDiv']; echo '<div id="'.$grandChildDiv.'">'; foreach($subcontainers as $greatGrandChild) { //extract info, etc... $greatGrandChildDiv = $greatGrandChild['greatGrandChildDiv']; echo '<div id="'.$greatGrandChildDiv.'">'; echo '</div>'; } echo '</div>'; } echo '</div>'; } echo '</div>'; } The results will look like this (ignore the attribute values as they are just test names): <div id="siteContainer"> <div id="header"> <div id="logoContainer">/div> <div id="logo"></div> <div id="links"></div> <div id="contactInfo"> <div id="logoText"> <div id="shortDiv"> <div class="headerText"></div> </div> </div> </div> </div> <div id="body"> <div id="longDiv"></div> <div id="greetings"></div> </div> <div> Basically, I take the resultset and create div tags for each record. The fun comes in iterating through each result and checking to see if it's a child of another element. If it is then it is echo'd between the parents div tags. The multiple foreach loops do this for as many records that are returned until there are none left to check. Would a recursive function work best in this situation? If so, any examples? I have not worked with recursives yet but have look at info online. Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-893614 Share on other sites More sharing options...
gevans Posted August 8, 2009 Share Posted August 8, 2009 It sounds like the nested foreach's is what you need. Without seeing the working code it would be hard to find another solution, though if that's working fine I'm not sure that another solution is needed. You could use a recursive function, but if I'm honest I'm not sure how to best write it for that amount of looping, especially without the actual code. Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-893616 Share on other sites More sharing options...
wildteen88 Posted August 8, 2009 Share Posted August 8, 2009 What is the out of echo '<pre>' . print_r($containers , true) . '</pre>'; echo '<pre>' . print_r($subcontainers , true) . '</pre>'; Looking at your code you do not need 4 nested foreach loops at all. Only two should do it Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-893617 Share on other sites More sharing options...
JsusSalv Posted August 8, 2009 Author Share Posted August 8, 2009 It sounds like the nested foreach's is what you need. Without seeing the working code it would be hard to find another solution, though if that's working fine I'm not sure that another solution is needed. You could use a recursive function, but if I'm honest I'm not sure how to best write it for that amount of looping, especially without the actual code. I've provided the working code and the results $containers is from a database query that returns the attribute values: siteContainer header logoContainer logo links contactInfo logoText shortDiv headerText body longDiv greetings Bu you are right, the nested loops is working well. However, I wanted something more dynamic than having to manually create ten nested foreach loops. Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-893794 Share on other sites More sharing options...
JsusSalv Posted August 8, 2009 Author Share Posted August 8, 2009 What is the out of echo '<pre>' . print_r($containers , true) . '</pre>'; echo '<pre>' . print_r($subcontainers , true) . '</pre>'; Looking at your code you do not need 4 nested foreach loops at all. Only two should do it Two works fine. But if there are divs that are nested within other divs then I need to account for that. I guess I'm looking for a better way to code this. Here are the db array results: The two arrays contain the same info except that $subcontainers has an extra column for listing which element is its parent element. Each array results is wrapped around div tags: foreach($containers as $parent){ echo '<div id="'.$parent['attribute_value'].'"></div>'; } Array results: echo '<pre>' . print_r($containers , true) . '</pre>'; ==> Array ( [attribute_value] => siteContainer ) Array ( [attribute_value] => header ) Array ( [attribute_value] => logoContainer ) Array ( [attribute_value] => logo ) Array ( [attribute_value] => logoText ) Array ( [attribute_value] => links ) Array ( [attribute_value] => contactInfo ) Array ( [attribute_value] => body ) Array ( [attribute_value] => longDiv ) Array ( [attribute_value] => shortDiv ) Array ( [attribute_value] => headerText ) Array ( [attribute_value] => greetings ) echo '<pre>' . print_r($subcontainers , true) . '</pre>'; ==> Array ( [parent_container_name] => siteContainer [attribute_value] => header ) Array ( [parent_container_name] => header [attribute_value] => logoContainer ) Array ( [parent_container_name] => header [attribute_value] => logo ) Array ( [parent_container_name] => contactInfo [attribute_value] => logoText ) Array ( [parent_container_name] => header [attribute_value] => links ) Array ( [parent_container_name] => header [attribute_value] => contactInfo ) Array ( [parent_container_name] => siteContainer [attribute_value] => body ) Array ( [parent_container_name] => body [attribute_value] => longDiv ) Array ( [parent_container_name] => logoText [attribute_value] => shortDiv ) Array ( [parent_container_name] => shortDiv [attribute_value] => headerText ) Array ( [parent_container_name] => body [attribute_value] => greetings ) Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-893802 Share on other sites More sharing options...
sasa Posted August 9, 2009 Share Posted August 9, 2009 try <?php $subcontainers =array( Array ( 'parent_container_name' => 'siteContainer', 'attribute_value' => 'header' ), Array ( 'parent_container_name' => 'header', 'attribute_value' => 'logoContainer' ), Array ( 'parent_container_name' => 'header', 'attribute_value' => 'logo' ), Array ( 'parent_container_name' => 'contactInfo', 'attribute_value' => 'logoText' ), Array ( 'parent_container_name' => 'header', 'attribute_value' => 'links' ) , Array ( 'parent_container_name' => 'header', 'attribute_value' => 'contactInfo' ) , Array ( 'parent_container_name' => 'siteContainer', 'attribute_value' => 'body' ) , Array ( 'parent_container_name' => 'body', 'attribute_value' => 'longDiv' ) , Array ( 'parent_container_name' => 'logoText', 'attribute_value' => 'shortDiv' ) , Array ( 'parent_container_name' => 'shortDiv', 'attribute_value' => 'headerText' ) , Array ( 'parent_container_name' => 'body', 'attribute_value' => 'greetings' ) ); foreach ($subcontainers as $item) $my_arr[$item['parent_container_name']][] = $item['attribute_value']; //print_r($my_arr); function my_div($array, $start,$ident=0){ echo str_repeat("\t",$ident),"<div id=\"$start\">"; if (isset($array[$start])) { echo "\n"; foreach ($array[$start] as $i)my_div($array,$i,$ident+1); } if (isset($array[$start])) echo str_repeat("\t",$ident); echo "</div>\n"; } my_div($my_arr,'siteContainer'); ?> Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-893933 Share on other sites More sharing options...
JsusSalv Posted August 9, 2009 Author Share Posted August 9, 2009 Sasa...you are awesome!!! This works as I had hoped it would. Thank you. I'm perplexed at how simple it looks yet it is so powerful! I owe you a latte my friend! How would I allow other database column info to trickle in there? For example, I have another column entitled 'attribute_name'. Would I append to the following? $my_arr[$item['parent_container_name']][] = $item['attribute_value'].$item['attribute_name']; Probably not but I've tried different configurations and I can't get other columns to spit out appropriately. Again, thank you for your help...much appreciated!!! Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-894154 Share on other sites More sharing options...
sasa Posted August 9, 2009 Share Posted August 9, 2009 try foreach ($subcontainers as $item) $my_arr[$item['parent_container_name']][] = $item; // add all $item to my_array //print_r($my_arr); function my_div($array, $start,$ident=0){ echo str_repeat("\t",$ident),"<div id=\"$start\">"; if (isset($array[$start])) { echo "\n"; foreach ($array[$start] as $i)my_div($array,$i['attribute_value'],$ident+1);//add what part of $i (item) i want } if (isset($array[$start])) echo str_repeat("\t",$ident); echo "</div>\n"; } my_div($my_arr,'siteContainer'); Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-894164 Share on other sites More sharing options...
JsusSalv Posted August 10, 2009 Author Share Posted August 10, 2009 Sasa: To add other db column info I would need to write the code like so: function my_div($array,$start,$atrName,$ident=0){ echo str_repeat(" ",$ident),'div '.$atrName.'="'.$start.'">'; if (isset($array[$start])) { echo "<br />"; foreach ($array[$start] as $i) my_div($array,$i['attribute_value'],$i['attribute_name'],$ident+1); //add what part of $i (item) i want } if (isset($array[$start])) echo str_repeat(" ",$ident); echo "/div> !-- end.$start --><br />"; } my_div($my_arr,'siteContainer','id'); However, I don't like that I have to hardcode the values, 'siteContainer','id', to get this to work: my_div($my_arr,'siteContainer','id'); Is there are workaround for that? I would like for it all to be dynamic. Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-894671 Share on other sites More sharing options...
JsusSalv Posted August 10, 2009 Author Share Posted August 10, 2009 Sasa, is there any way to not make your code into a function? I'm finding the code to be more difficult to manipulate as a function. Is there any other way to make this work without being a function? Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-895053 Share on other sites More sharing options...
JsusSalv Posted August 11, 2009 Author Share Posted August 11, 2009 Thank you everyone for the help. Although a tad tougher to manipulate I am testing Sasa's recursive function with great results. Thank you! Quote Link to comment https://forums.phpfreaks.com/topic/169344-solved-one-for-loop-to-simplify-multiple-nested-foreach-loops/#findComment-895432 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.