В настоящее время я работаю над классом создания общей формы и вчера имел проблему. Я сделал фрагмент, чтобы воспроизвести проблему.Удаление элементов из массива в пределах foreach
По существу, я хочу удалить элементы, которые сгруппированы из массива исходных элементов после того, как вся группа была нарисована, и я делаю это, перебирая массив элементов.
Фрагмент кода должен охватывать проблему, я что-то пропустил здесь? По моим сведениям, удаление элемента в то время как foreach полностью безопасно и законно, поскольку foreach внутренне использует только копию, которая может быть изменена во время цикла.
$ids = array('a' => array(), 'b' => array(), 'c' => array());
$groups['g1'] = array('a', 'c');
foreach($ids as $id => $element) {
//var_dump($ids);
$g_id = '';
// search the id in all groups
foreach($groups as $group_id => $group) {
if(in_array($id, $group)) {
$g_id = $group_id;
break;
}
}
// element is part of a group
if($g_id !== '') {
//echo $g_id;
// element a and c gets unset within loop and should not be in $ids anymore
foreach($groups[$g_id] as $field_id) {
unset($ids[$field_id]);
echo $field_id;
}
unset($groups[$g_id]);
} else {
if($id === 'a' || $id === 'c')
echo $id;
}
}
элемент «с» получает сбросить в пределах Foreach (группы ..) цикл, но потом снова выводятся в другом отделении. Также, когда я сначала var_dump ($ fields), я всегда получаю 'a', 'b' и 'c' внутри. Я использую PHP 5.4.7.
Заранее спасибо
EDIT: я сделал ошибку в примере кода, его в настоящее время обновляется. Разумеется, все комментарии об использовании неправильного индекса (это было бы 0,1 и т. Д.). Значения при использовании var_dump не установлены сейчас, но я все равно попадаю в else с 'c' один раз.
EDIT2: Im не сделано с исходным кодом, но после прочтения комментариев, которые я в настоящее время придумал следующее решение отправленного фрагмента кода выше:
$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 as $b) {
unset($ids[$b]);
}
});
print_r($ids);
или
$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 as $g) {
if(in_array($i,$g)) {
$in_both = array_intersect(array_keys($ids),$g);
}
}
foreach($in_both as $b) {
unset($ids[$b]);
}
});
print_r($ids);
Использование foreach не работает для меня в этом случае, потому что мне нужно изменить массив $ ids, в то время как цикл выполняет итерацию по нему.
В самом самом базовом положении код что-то вроде этого:
$ids = array('a', 'b');
while(count($ids)) {
array_pop($ids);
echo 'pop';
}
echo 'empty';
Allthough Еогеасп может изменить исходные значения из массива не изменит копию массива, используемого для итерации как NL-х уже заявлено. Благодаря Passerby за идею использования array_walk для этого.
EDIT3: Обновлен код, отрезанный еще раз. Второй отрезанный allthough ведет себя также неопределенным. Удаление элементов из массива при итерации по нему кажется плохой идеей.
Посмотрите [здесь] (http://stackoverflow.com/questions/10057671/how-foreach-actually-works). Вместо этого я предлагаю использовать цикл 'for'. – BlitZ
'$ ids [$ field_id]' в вашем примере не существует, потому что он будет интерпретировать '$ ids [" a "]', а не '$ ids [0]'. Кроме того, я не могу ответить на ваш вопрос, не могли бы вы сделать это немного более понятным, например: «У меня есть два массива, которые выглядят как этот [код массива], и я хотел бы удалить, если ... так что это может быть позже выглядите так [array code]. "? – Passerby
@Passerby Отличное наблюдение +1. Но эта ошибка ничего не меняет в выходе. Если вы измените '$ ids = array ('a', 'b', 'c');' в '$ ids = array ('a' => 'a', 'b' => 'b', 'c '=>' c '); 'ничего не меняется. –