Подтвердить что ты не робот

While (list ($ key, $value) = each ($ array)) vs. foreach ($ array as $key => $value)?

Недавно я испытал эту странную проблему:

while(list($key, $value) = each($array))

не перечисляло все значения массива, заменив их на...

foreach($array as $key => $value)

... работал отлично.

И теперь мне интересно. В чем разница между этими двумя?

4b9b3361

Ответ 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