Поиск…


Синтаксис

  • for ($ i = 0; $ i <count ($ array); $ i ++) {incremental_iteration (); }
  • for ($ i = count ($ array) - 1; $ i> = 0; $ i--) {reverse_iteration (); }
  • foreach ($ data as $ datum) {}
  • foreach ($ data as $ key => $ datum) {}
  • foreach ($ data as & $ datum) {}

замечания

Сравнение методов для итерации массива

метод преимущество
foreach Простейший метод для итерации массива.
foreach по ссылке Простой метод для итерации и изменения элементов массива.
for с дополнительных индекса Позволяет выполнять итерацию массива в свободной последовательности, например, пропускать или реверсировать несколько элементов
Внутренние указатели массива Больше нет необходимости использовать цикл (чтобы он мог выполнять итерацию после каждого вызова функции, получения сигнала и т. Д.),

Итерация нескольких массивов вместе

Иногда необходимо объединить два массива одинаковой длины, например:

$people = ['Tim', 'Tony', 'Turanga'];
$foods = ['chicken', 'beef', 'slurm'];

array_map - это самый простой способ сделать это:

array_map(function($person, $food) {
    return "$person likes $food\n";
}, $people, $foods);

который будет выводить:

Tim likes chicken
Tony likes beef
Turanga likes slurm

Это можно сделать с помощью общего индекса:

assert(count($people) === count($foods));
for ($i = 0; $i < count($people); $i++) {
    echo "$people[$i] likes $foods[$i]\n";
}

Если у двух массивов нет инкрементных ключей, array_values($array)[$i] может использоваться для замены $array[$i] .

Если оба массива имеют одинаковый порядок ключей, вы также можете использовать цикл foreach-with-key на одном из массивов:

foreach ($people as $index => $person) {
    $food = $foods[$index];
    echo "$person likes $food\n";
}

Отдельные массивы могут быть закодированы только в том случае, если они имеют одинаковую длину и имеют одинаковое имя ключа. Это означает, что если вы не предоставите ключ, и они пронумерованы, вы будете в порядке, или если вы назовете ключи и поместите их в одном порядке в каждом массиве.

Вы также можете использовать array_combine .

$combinedArray = array_combine($people, $foods);
// $combinedArray = ['Tim' => 'chicken', 'Tony' => 'beef', 'Turanga' => 'slurm'];

Затем вы можете пройти через это, сделав то же самое, что и раньше:

foreach ($combinedArray as $person => $meal) {
    echo "$person likes $meal\n";
}

Использование инкрементного индекса

Этот метод работает, увеличивая число от 0 до наибольшего индекса в массиве.

$colors = ['red', 'yellow', 'blue', 'green'];
for ($i = 0; $i < count($colors); $i++) {
    echo 'I am the color ' . $colors[$i] . '<br>';
}

Это также позволяет итерации массива в обратном порядке без использования array_reverse , что может привести к накладным расходам, если массив большой.

$colors = ['red', 'yellow', 'blue', 'green'];
for ($i = count($colors) - 1; $i >= 0; $i--) {
    echo 'I am the color ' . $colors[$i] . '<br>';
}

Этот метод можно легко пропустить или перемотать индекс.

$array = ["alpha", "beta", "gamma", "delta", "epsilon"];
for ($i = 0; $i < count($array); $i++) {
    echo $array[$i], PHP_EOL;
    if ($array[$i] === "gamma") {
        $array[$i] = "zeta";
        $i -= 2;
    } elseif ($array[$i] === "zeta") {
        $i++;
    }
}

Выход:

alpha
beta
gamma
beta
zeta
epsilon

Для массивов, которые не имеют инкрементных индексов (включая массивы с индексами в обратном порядке, например [1 => "foo", 0 => "bar"] , ["foo" => "f", "bar" => "b"] ), это невозможно сделать напрямую. array_values array_keys можно использовать array_values или array_keys :

$array = ["a" => "alpha", "b" => "beta", "c" => "gamma", "d" => "delta"];
$keys = array_keys($array);
for ($i = 0; $i < count($array); $i++) {
    $key = $keys[$i];
    $value = $array[$key];
    echo "$value is $key\n";
}

Использование указателей внутренних массивов

Каждый экземпляр массива содержит внутренний указатель. Управляя этим указателем, различные элементы массива могут быть извлечены из одного и того же вызова в разное время.

Использование each

Каждый вызов для each() возвращает ключ и значение текущего элемента массива и увеличивает указатель внутреннего массива.

$array = ["f" => "foo", "b" => "bar"];
while (list($key, $value) = each($array)) {
    echo "$value begins with $key";
}

Использование next

$array = ["Alpha", "Beta", "Gamma", "Delta"];
while (($value = next($array)) !== false) {
    echo "$value\n";
}

Обратите внимание, что в этом примере предполагается, что никакие элементы в массиве не идентичны логическому false . Чтобы предотвратить такое предположение, используйте key чтобы проверить, достиг ли внутренний указатель до конца массива:

$array = ["Alpha", "Beta", "Gamma", "Delta"];
while (key($array) !== null) {
    echo current($array) . PHP_EOL;
    next($array);
}

Это также облегчает итерацию массива без прямого цикла:

class ColorPicker {
    private $colors = ["#FF0064", "#0064FF", "#64FF00", "#FF6400", "#00FF64", "#6400FF"];
    public function nextColor() : string {
        $result = next($colors);
        // if end of array reached
        if (key($colors) === null) {
            reset($colors);
        }
        return $result;
    }
}

Использование foreach

Прямой контур

foreach ($colors as $color) {
    echo "I am the color $color<br>";
}

Петля с ключами

$foods = ['healthy' => 'Apples', 'bad' => 'Ice Cream'];
foreach ($foods as $key => $food) {
    echo "Eating $food is $key";
}

Петля по ссылке

В циклах foreach в приведенных выше примерах изменение значения ( $color или $food ) напрямую не изменяет его значение в массиве. Оператор & требуется, чтобы это значение указывало на элемент в массиве.

$years = [2001, 2002, 3, 4];
foreach ($years as &$year) {
    if ($year < 2000) $year += 2000;
}

Это похоже на:

$years = [2001, 2002, 3, 4];
for($i = 0; $i < count($years); $i++) { // these two lines
    $year = &$years[$i];                // are changed to foreach by reference
    if($year < 2000) $year += 2000;
}

совпадение

Массивы PHP могут быть изменены любым способом во время итерации без проблем параллелизма (в отличие от, например, Java List s). Если массив повторяется по ссылке, на последующие итерации будут влиять изменения в массиве. В противном случае изменения в массиве не повлияют на последующие итерации (как если бы вы повторяли копию массива). Сравнение циклов по значению:

$array = [0 => 1, 2 => 3, 4 => 5, 6 => 7];
foreach ($array as $key => $value) {
    if ($key === 0) {
        $array[6] = 17;
        unset($array[4]);
    }
    echo "$key => $value\n";
}

Выход:

0 => 1
2 => 3
4 => 5
6 => 7

Но если массив повторяется со ссылкой,

$array = [0 => 1, 2 => 3, 4 => 5, 6 => 7];
foreach ($array as $key => &$value) {
    if ($key === 0) {
        $array[6] = 17;
        unset($array[4]);
    }
    echo "$key => $value\n";
}

Выход:

0 => 1
2 => 3
6 => 17

Набор значений ключа 4 => 5 больше не повторяется, а 6 => 7 изменяется на 6 => 17 .

Использование ArrayObject Iterator

Php-матрица позволяет вам изменять и отменять значения при повторении массивов и объектов.

Пример:

$array = ['1' => 'apple', '2' => 'banana', '3' => 'cherry'];

$arrayObject = new ArrayObject($array);

$iterator = $arrayObject->getIterator();

for($iterator; $iterator->valid(); $iterator->next()) {
    echo $iterator->key() . ' => ' . $iterator->current() . "</br>";
}

Выход:

1 => apple
2 => banana
3 => cherry


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow