php - Unsetting elements from array within foreach -
i'm working on generic form creation class , had issue yesterday. made snippet reproduce problem.
essentially want delete elements grouped original elements array after whole group has been drawn , i'm doing while looping on elements array.
the code snippet should cover problem, missing here? knowledge deleting element while foreach safe , legal since foreach internally uses copy may modified during loop.
$ids = array('a' => array(), 'b' => array(), 'c' => array()); $groups['g1'] = array('a', 'c'); foreach($ids $id => $element) { //var_dump($ids); $g_id = ''; // search id in groups foreach($groups $group_id => $group) { if(in_array($id, $group)) { $g_id = $group_id; break; } } // element part of group if($g_id !== '') { //echo $g_id; // element , c gets unset within loop , should not in $ids anymore foreach($groups[$g_id] $field_id) { unset($ids[$field_id]); echo $field_id; } unset($groups[$g_id]); } else { if($id === 'a' || $id === 'c') echo $id; } }
element 'c' gets unset within foreach(groups ..) loop afterwards again outputted in else branch. when var_dump($fields) @ beginning 'a', 'b' , 'c' inside. i'm using php 5.4.7.
thanks in advance
edit: made mistake in sample code, updated. comments using wrong index (it have been 0,1 etc) correct of course. values when using var_dump unset now, still else 'c' 1 time.
edit2: im not done original code after reading through comments came following solution posted code snippet above:
$ids=array("a"=>array(),"b"=>array(),"c"=>array(),"d"=>array(),"e"=>array()); $groups=array(array("a"),array("c", "e")); array_walk($groups,function($v,$i)use(&$ids){ $in_both = array_intersect(array_keys($ids),$v); //var_dump($in_both); foreach($in_both $b) { unset($ids[$b]); } }); print_r($ids);
or
$ids=array("a"=>array(),"b"=>array(),"c"=>array(),"d"=>array(),"e"=>array()); $groups=array(array("a"),array("c")); array_walk($ids,function($v,$i)use(&$ids, $groups){ $in_both = array(); foreach($groups $g) { if(in_array($i,$g)) { $in_both = array_intersect(array_keys($ids),$g); } } foreach($in_both $b) { unset($ids[$b]); } }); print_r($ids);
using foreach not work me in case, because need change $ids array while loop iterating on it.
in basic situation code this:
$ids = array('a', 'b'); while(count($ids)) { array_pop($ids); echo 'pop'; } echo 'empty';
allthough foreach can change original values array not change copy of array used iteration nl-x stated. passerby idea of using array_walk this.
edit3: updated code snipped once more. second snipped allthough behaves undefined well. deleting elements array while iterating on seems bad idea.
chris, if understand correctly, don't expect 'c' outputted in else branch?
but should outputted. logic is:
- you foreach ids , start id 'a'.
- then clear ids , c ids and delete group g1 contained 'a'. during step deleted ids outputted, being , c. (clearing , c ids have no impact on
foreach($ids $id)
foreach continue untouched copy after ids array has been cleared.) - then id 'b': not found in group. (actually, there isn't group left anyway)
- so 'b' enter else branch. if() inside else branch prevents output
- then id 'c', not found in group, because have already deleted group g1! there no groups left, remember?
- so 'c' enter else branch. , time if() inside else branch allows output! output being c
so total output indeed acc.
it know foreach() continues untouched copy after elements cleared, specific php thing. other language no same.
Comments
Post a Comment