While (list ($ key, $value) = each ($ array)) vs. foreach ($ array as $key => $value)?
Недавно я испытал эту странную проблему:
while(list($key, $value) = each($array))
не перечисляло все значения массива, заменив их на...
foreach($array as $key => $value)
... работал отлично.
И теперь мне интересно. В чем разница между этими двумя?
Ответы
Ответ 1
Если раньше вы проходили массив? each()
запоминает свою позицию в массиве, поэтому, если вы не reset()
, вы можете пропустить пункты.
reset($array);
while(list($key, $value) = each($array))
Для того, что стоит этот метод обхода массива, древний и был заменен более идиоматическим foreach. Я бы не использовал его, если вы специально не хотите использовать его по одному пункту.
массив каждый (массив и массив $)
Возвращает текущую пару ключей и значений из массива и продвигает курсор массива.
После выполнения each()
курсор массива будет оставлен на следующем элементе массива или за последним элементом, если он попадет в конец массива. Вы должны использовать reset()
, если хотите снова пересечь массив, используя each
.
(Источник: Руководство по PHP)
Ответ 2
Ну, одно отличие состоит в том, что each()
будет работать только с массивами (хорошо работает только право). foreach
будет работать на любом объекте, который реализует интерфейс traversable
(который, конечно же, включает встроенный тип массива).
В foreach может быть микро-оптимизация. В принципе, foreach эквивалентен следующему:
$array->rewind();
while ($array->valid()) {
$key = $array->key();
$value = $array->current();
// Do your code here
$array->next();
}
В то время как each
в основном делает следующее:
$return = $array->valid() ? array($array->key(), $array->current()) : false;
$array->next();
return $return;
Таким образом, три строки одинаковы для обоих. Они оба очень похожи. Могут быть некоторые микрооптимизации в том, что each
не нужно беспокоиться о интерфейсе traversable
... Но это будет в лучшем случае незначительным. Но это также будет компенсировано выполнением логического литья и проверки php-кода vs foreach
скомпилированного C... Не говоря уже о том, что в вашем коде while/each
вы вызываете две языковые конструкции и одну функцию, тогда как с foreach
это одна языковая конструкция...
Не говоря уже о том, что foreach
БОЛЬШЕ читаем ИМХО... Так что легче читать и более гибко означает, что для меня - foreach
- явный победитель. (чтобы не сказать, что each
не использует его, но лично мне он никогда не нужен)...
Ответ 3
Предупреждение! Foreach создает копию массива, поэтому вы не можете ее изменить , в то время как foreach выполняет итерацию по ней. each()
все еще имеет цель и может быть очень полезен, если вы делаете живые изменения в массиве, перебирая его элементы и индексы.
// Foreach creates a copy
$array = [
"foo" => ['bar', 'baz'],
"bar" => ['foo'],
"baz" => ['bar'],
"batz" => ['end']
];
// while(list($i, $value) = each($array)) { // Try this next
foreach($array as $i => $value) {
print $i . "\n";
foreach($value as $index) {
unset($array[$index]);
}
}
print_r($array); // array('baz' => ['end'])
Оба foreach
и while
завершат их циклы, и массив "$array
" будет изменен. Однако цикл foreach не изменялся, когда он был циклическим, поэтому он все еще повторялся по каждому элементу, даже если мы удалили их.
Обновление: этот ответ не является ошибкой.
Я думал, что этот ответ был довольно прост, но большинство пользователей здесь не могут оценить конкретные детали, которые я упоминаю здесь.
Разработчики, которые создали приложения, использующие libdom (например, удаляющие элементы) или другие интенсивные фильтры map/list/dict, могут подтвердить важность того, что я сказал здесь.
Если вы не понимаете этого ответа, он однажды вас укусит.
Ответ 4
Если вы передали each
объект для итерации, руководство PHP предупреждает, что оно может иметь неожиданные результаты.
Что именно находится в $array