В то время как (список ($ ключ, $ значение) = каждый ($ массив)) против foreach ($ массив как $ ключ => $ значение)? - PullRequest
34 голосов
/ 22 июля 2010

Недавно я столкнулся с этой странной проблемой:

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

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

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

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

И мне любопытно ... в чем разница между этими двумя?

Ответы [ 4 ]

52 голосов
/ 22 июля 2010

Вы ранее проходили массив? each() запоминает свою позицию в массиве, поэтому, если вы не reset(), вы можете пропустить элементы.

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

Для чего стоит этот метод обхода массива является древним и был заменен более идиоматическим foreach. Я бы не стал использовать его, если вы специально не хотите воспользоваться преимуществом его индивидуального характера.

массив каждый ( массив & $ массив)

Возвращает текущую пару ключ-значение из массива и перемещает курсор массива.

После выполнения each() курсор массива будет оставлен на следующем элементе массива или за последним элементом, если он достигнет конца массива. Вы должны использовать reset(), если хотите снова пройти массив, используя each.

(Источник: Руководство по PHP )

12 голосов
/ 22 июля 2010

Ну, одно отличие состоит в том, что 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-коде против скомпилированного C foreach ... Не говоря уже о том, что в вашем коде while/each вы вызываете две языковые конструкции и одну функцию,тогда как с foreach это единственная языковая конструкция ...

Не говоря уже о том, что foreach НАМНОГО более читабельно ИМХО ... Так легче читать и более гибко означает, что -то- foreach явный победитель.(это не значит, что each не имеет смысла, но лично я никогда не нуждался в этом) ...

8 голосов
/ 25 мая 2015

Предупреждение! 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 не изменился во время выполнения цикла, поэтому он повторялся по каждому элементу, даже если мы их удалили.

Обновление: этот ответ не является ошибкой.

IЯ подумал, что этот ответ довольно прост, но, похоже, большинство пользователей здесь не в состоянии оценить конкретные детали, которые я здесь упоминаю.

Разработчики, создавшие приложения с использованием libdom (например, удаление элементов) или другой интенсивной карты.Фильтрация / list / dict может подтвердить важность того, что я здесь сказал.

Если вы не поймете этот ответ, он однажды укусит вас.

1 голос
/ 22 июля 2010

Если вы передали each объект для итерации, руководство по PHP предупреждает, что оно может привести к неожиданным результатам.

Что именно в $array

...