|
ока,
что
Часть III. Основы языка PHP 176
позволяет использовать вызов key() в контексте второго выражения for). Ну а
функция Next() просто перемещает текущий элемент на одну позицию вперед.
На самом деле, две простейшие функции, — Reset() и Next(), — помимо выпол-
нения своей основной задачи, еще и возвращают некоторые значения, а именно:
r функция Reset() возвращает значение первого элемента массива (или пустую
строку, если массив пуст);
r функция Next() возвращает значение элемента, следующего за текущим (или
пустую строку, если такого элемента нет).
Иногда (кстати, гораздо реже) бывает нужно перебрать массив с конца, а не с
начала.
Для этого воспользуйтесь такой конструкцией:
for(End($Names); ($k=key($Names)); Prev($Names))
echo "Возраст $k — {$Names[$k]} лет\n";
По контексту несложно сообразить, как это работает. Функция End() устанавливает
позицию текущего элемента в конец массива, а Prev() передвигает ее на один эле-
мент назад.
И еще. В PHP имеется функция current(). Она очень напоминает key(), только
возвращает не ключ, а величину текущего элемента (если он не указывает на конец
массива).
Недостатки косвенного перебора
Давайте теперь поговорим о достоинствах и недостатках такого вида перебора
масси-
вов. Основное достоинство — "читабельность" и ясность кода, а также то, что
массив
мы можем перебрать как в одну, так и в другую сторону. Однако существуют и не-
достатки.
Одинаковые ключи
Первый недостаток довольно фундаментален: мы не можем одновременно перебирать
массив в двух вложенных циклах или функциях. Причина вполне очевидна: второй
вложенный for "испортит" положение текущего элемента у первого for’а. К сожале-
нию, эту проблему никак нельзя обойти (разве что сделать копию массива, и во
внут-
реннем цикле работать с ней, но это не очень-то красиво). Однако практика
показы-
вает, что такие переборы встречаются крайне редко.
Нулевой ключ
А что, если в массиве встретится ключ 0 (хотя для массивов имен это,
согласитесь,
маловероятно)? Давайте еще раз посмотрим на первый цикл перебора:
for(Reset($Names); ($k=key($Names)); Next($Names))
echo "Возраст $k — {$Names[$k]} лет\n";
Глава 10. Ассоциативные массивы 177
В этом случае выражение ($k=key($Names)), естественно, будет равно нулю, и
цикл оборвется, чего бы нам совсем не хотелось.
Именно по этим причинам разработчики PHP придумали другой, хотя и менее уни-
версальный, но гораздо более удобный метод перебора массивов, о котором сейчас
и
пойдет речь.
Прямой перебор массива
В отличие от косвенного перебора (когда сначала вычисляется очередной ключ, а
уж
затем по нему косвенно находится значение элемента массива), прямой перебор ла-
коничнее и гораздо более прост. Идея метода заключается в том, чтобы сразу на
каж-
дом "витке" цикла одновременно получать и ключ, и значение текущего элемента.
Классический перебор
Давайте опять вернемся к нашему примеру, в котором массив $Names хранил связь
имен людей и их возрастов. Вот как можно перебрать этот массив при помощи пря-
мого перебора:
for(Reset($Names); list($k,$v)=each($Names); /*пусто*/)
echo "Возраст $k — $v\n";
В самом начале заголовка цикла мы видим нашу старую знакомую Reset(). Дальше
переменным $k и $v присваивается результат работы функции each(). Третье усло-
вие цикла попросту отсутствует (чтобы это подчеркнуть, я включил на его место
ком-
ментарий).
Что делает функция each()? Во-первых, возвращает небольшой массив (я бы даже
сказал, список), нулевой элемент которого хранит величину ключа текущего
элемента
массива $Names, а первый — значение текущего элемента. Во-вторых, она продвига-
ет указатель текущего элемента к следующей позиции. Следует заметить, что если
следующего элемента в массиве нет, то функция возвращает не список, а false.
Именно поэтому она и размещена в условии цикла for. Становится ясно, почему мы
не указали третий блок
|
|