TankedShark Posted December 4, 2008 Share Posted December 4, 2008 Is there any way to reset a foreach loop, or do I have to use a for loop instead? I'm trying to get this to print "1 5 10 1 5 10 " <?php $arrA = array(1, 5, 10); $firstRun = true; foreach ($arrA as $value) { echo $value.' '; if ( ($firstRun == true) && ($value == 10) ) { $firstRun = false; reset($arrA); } } ?> Quote Link to comment Share on other sites More sharing options...
premiso Posted December 4, 2008 Share Posted December 4, 2008 I do not think it is possible, but you could make your own function that is recursive... <?php $arrA = array(1, 5, 10); $firstRun = true; foreachTwice($arrA, true); function foreachTwice($array, $continue) { foreach ($array as $value) { echo $value.' '; if ( ($continue) && ($value == 10) ) { foreachTwice($array, false); } } } ?> That can also be manipulated to go so much further to, as it is it will only run twice. Quote Link to comment Share on other sites More sharing options...
TankedShark Posted December 4, 2008 Author Share Posted December 4, 2008 This is already going to be used in the context of a recursive function. It's not the output that I'm looking for, it's the sequence. Maybe this will better illustrate it: Desired output is "1 5 1 5 10 " <?php $arrA = array(1, 5, 10); $firstRun = true; foreach ($arrA as $value) { echo $value.' '; if ( ($firstRun == true) && ($value == 5) ) { $firstRun = false; reset($arrA); } } ?> Quote Link to comment Share on other sites More sharing options...
premiso Posted December 4, 2008 Share Posted December 4, 2008 edit: removed below and re-thinking it. <?php $arrA = array(1, 5, 10); $firstRun = true; foreachLoop($arrA, 5); function foreachLoop($array, $endAt=false) { foreach ($array as $value) { echo $value.' '; if (!$endAt) continue; // if endat is false just continue and skip below if (($value == $endAt) ) { foreachLoop($array, false); break; } } } ?> That would work, that way you give it a value and once it hits that it breaks out etc. As for which is better, this or a for loop really it is your call. But foreach doesn't have a built in function to do that as far as I know. Quote Link to comment Share on other sites More sharing options...
dclamp Posted December 4, 2008 Share Posted December 4, 2008 why dont you just edit your array to include the desired output? Quote Link to comment Share on other sites More sharing options...
TankedShark Posted December 4, 2008 Author Share Posted December 4, 2008 edit: removed below and re-thinking it. code That would work, that way you give it a value and once it hits that it breaks out etc. As for which is better, this or a for loop really it is your call. But foreach doesn't have a built in function to do that as far as I know. I guess my example isn't a good enough parallel to my situation, as I have no idea how to implement your solution. What I'm ultimately trying to do is to flatten a multi-dimensional array, with elements of Glue inserted between the elements of a childless sub-array, and elements of Break inserted between the elements of a parent array. Since my current function iterates through the array passed to it only once, it will insert A between non-array elements even if an array element is present further down the line. If I run it on $arrA, defined as array(1, 2, array(3, 4), 5), I want the result equal array(1, B, 2, B, 3, G, 4, B, 5). In its present form, the result equals array(1, G, 2, G, 3, G, 4, B, 5), because it assumes that the top-level array is childless until it finds otherwise. Here's the code, with the faulty reset: <?php ///////////// // brackets are incorrect right now ///////////// function flat_insert($source, $glue, $break) { if (!is_array($source)) { return null; } $stack1 = array(); //this will be returned $child = true; foreach ($source as $value) { if ((is_array($value)) && ($child == true)) { //if we find an array $child = false; reset($source); //re-start loop $stack1 = array(); //clear stack for restart } else if ((is_array($value)) && ($child == false)) { //if we already know we're in a parent, and we find a sub-array foreach (flat_insert($value, $glue, $break) as $v2) { //iterate through recursed sub-array $stack1[] = $v2; } unset($v2); if ($value != end($source)) { //only insert fill if we're not at the end $stack1[] = $break; } } else if ($child == false) { //parent array, current is not a sub-array $stack1[] = $value; if ($value != end($source)) { $stack1[] = $break; } else { //presume childless $stack1[] = $value; if ($value != end($source)) { $stack1[] = $glue; } } } unset($value); return $stack; } ?> Quote Link to comment Share on other sites More sharing options...
TankedShark Posted December 4, 2008 Author Share Posted December 4, 2008 Alright, I got it. The trick is to pass a new variable by reference into all extra elements, then change the value of the variable at the end of the function based on whether it's a parent or child. Here's the function and some sample outputs: <?php function flat_insert2($source, $glue, $break) { if (!is_array($source)) { return null; } $stack1 = array(); $child = true; $insert = $glue; foreach ($source as $value) { if (is_array($value)) { //if we find a sub-array in current element $child = false; foreach (flat_insert2($value, $glue, $break) as $v2) { //iterate through recursed sub-array $stack1[] = $v2; } unset($v2); } else { //current element is not an array $stack1[] = $value; } $stack1[] = &$insert; //pass insert as reference } unset($value); array_pop($stack1); //remove trailing insert if ($child == false) { $insert = $break; } return $stack1; } ?> <?php $arrF = array(8, 9); $arrE = array(6, 7); $arrD = array(4, 5); $arrC = array($arrD, $arrE, $arrF, 10); $arrB = array(2, 3, $arrC); $arrA = array(1, $arrB, 11); echo 'Array A: '.implode(flat_insert2($arrA, '-', ' ')).'<br />'; echo 'Array B: '.implode(flat_insert2($arrB, '-', ' ')).'<br />'; echo 'Array C: '.implode(flat_insert2($arrC, '-', ' ')).'<br />'; echo 'Array D: '.implode(flat_insert2($arrD, '-', ' ')).'<br />'; ?> Output: Array A: 1 2 3 4-5 6-7 8-9 10 11 Array B: 2 3 4-5 6-7 8-9 10 Array C: 4-5 6-7 8-9 10 Array D: 4-5 Quote Link to comment 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.