Деление массивов на фрагменты в PHP: полное руководство
Разделение массива на части
Как разбить массив на равные части с помощью одной встроенной функции?
Наиболее эффективный и простой способ - функция array_chunk. Она делит массив на фрагменты заданного размера и возвращает многомерный массив, где каждый элемент - это часть исходного.
$arr = [1, 2, 3, 4, 5, 6, 7];
$chunks = array_chunk($arr, 3);
print_r($chunks);Php разделить массив (разделение массива на части в php)
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 4
[1] => 5
[2] => 6
)
[2] => Array
(
[0] => 7
)
)
Пояснение:
- Первый аргумент - массив.
- Второй - размер части.
- Последний фрагмент может быть короче, если число элементов не кратно размеру.
Проблема: при использовании ассоциативных массивов ключи нумеруются заново. Как сохранить исходные ключи?
Третий необязательный параметр $preserve_keys (true) сохранит строковые или целочисленные ключи.
$assoc = ['a'=>1, 'b'=>2, 'c'=>3, 'd'=>4];
$chunks = array_chunk($assoc, 2, true);
print_r($chunks);
Array
(
[0] => Array
(
[a] => 1
[b] => 2
)
[1] => Array
(
[c] => 3
[d] => 4
)
)
Без true ключи сбрасываются в числовой индекс.
Цели и случаи использования:
- Пагинация данных (разбивка на страницы).
- Пакетная обработка больших массивов (например, отправка по частям в API).
- Группировка элементов для отображения в сетке (по N элементов в строке).
Как разделить массив с помощью цикла и array_slice?
Когда требуется гибкость (например, разные размеры частей или сложная логика), можно использовать цикл с array_slice. Этот способ не изменяет исходный массив.
$arr = [1, 2, 3, 4, 5, 6, 7];
$chunkSize = 3;
$result = [];
for ($i = 0; $i < count($arr); $i += $chunkSize) {
$result[] = array_slice($arr, $i, $chunkSize);
}
print_r($result);
// Результат идентичен предыдущему
Проблема: производительность при очень больших массивах: count вызывается на каждой итерации.
Решение: вычислить общее количество до цикла.
$total = count($arr);
for ($i = 0; $i < $total; $i += $chunkSize) { ... }
Цель: когда нужно динамически определять размер части или прерывать разбиение по условию.
Как разбить массив на части, удаляя элементы из исходного (array_splice)?
array_splice удаляет часть массива и возвращает её. Можно повторять, пока массив не опустеет.
$arr = [1, 2, 3, 4, 5, 6, 7];
$chunks = [];
while (!empty($arr)) {
$chunks[] = array_splice($arr, 0, 3);
}
print_r($chunks);
Проблема: исходный массив изменяется - это может быть нежелательно, если он нужен дальше.
Решение: сделать копию или использовать array_slice.
Цель: когда исходный массив больше не нужен, и требуется экономия памяти.
Как разделить массив на части с помощью foreach и накопления?
Подходит для ручного контроля. Например, можно разбивать по условию, а не по фиксированному размеру.
$arr = [1, 2, 3, 4, 5, 6, 7];
$chunkSize = 3;
$chunks = [];
$sub = [];
foreach ($arr as $value) {
$sub[] = $value;
if (count($sub) == $chunkSize) {
$chunks[] = $sub;
$sub = [];
}
}
if (!empty($sub)) {
$chunks[] = $sub;
}
print_r($chunks);
Проблема: легко допустить ошибку с последней частью, если она неполная.
Не забывайте добавлять остаток после цикла.
Цель: когда требуется дополнительная обработка каждого элемента перед добавлением в часть.
Расширенные примеры разделения массивов
Здесь приведены подробные примеры с пояснениями и выводом результатов.
Пример 1. Разбиение на части с сохранением ключей ассоциативного массива
$users = [
'u1' => 'Alice',
'u2' => 'Bob',
'u3' => 'Charlie',
'u4' => 'David',
'u5' => 'Eve'
];
// Разбить на две группы по 2 и 3 элемента (последняя часть неполная)
$groups = array_chunk($users, 2, true);
echo "Группы пользователей:\n";
foreach ($groups as $i => $group) {
echo "Группа " . ($i+1) . ":\n";
foreach ($group as $key => $name) {
echo " $key => $name\n";
}
}
Группы пользователей: Группа 1: u1 => Alice u2 => Bob Группа 2: u3 => Charlie u4 => David Группа 3: u5 => Eve
Без параметра true ключи стали бы числами 0,1,2,...
Пример 2. Разделение на N равных частей (насколько возможно)
Часто требуется разбить массив на заданное количество частей, а не на части фиксированной длины.
function splitIntoNParts($array, $parts) {
$length = count($array);
if ($parts <= 0 || $parts > $length) {
return [$array];
}
$chunkSize = (int)ceil($length / $parts);
// Последняя часть может быть меньше
$chunks = array_chunk($array, $chunkSize);
// Если количество частей больше, чем получилось, объединим последние (обычно не нужно)
return $chunks;
}
$arr = range(1, 10); // 10 элементов
$parts = 3;
$result = splitIntoNParts($arr, $parts);
print_r($result);
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
[1] => Array
(
[0] => 5
[1] => 6
[2] => 7
)
[2] => Array
(
[0] => 8
[1] => 9
[2] => 10
)
)
Обратите внимание: первая часть получила 4 элемента, остальные по 3. Функция ceil даёт верхнее округление. Можно также использовать floor и корректировать остаток.
Пример 3. Пагинация с array_chunk
Разобьём массив на страницы по 4 элемента и выведем номера страниц.
$items = ['Товар 1','Товар 2','Товар 3','Товар 4','Товар 5','Товар 6','Товар 7','Товар 8','Товар 9','Товар 10'];
$perPage = 4;
$pages = array_chunk($items, $perPage);
$totalPages = count($pages);
echo "Всего страниц: $totalPages\n\n";
echo "Товары на первой странице:\n";
print_r($pages[0]);
Всего страниц: 3
Товары на первой странице:
Array
(
[0] => Товар 1
[1] => Товар 2
[2] => Товар 3
[3] => Товар 4
)
Третья страница будет содержать два последних товара. Для удобства можно передавать номер страницы и получать нужный фрагмент через array_slice без разбивки всего массива.
Пример 4. Разделение с обработкой каждого элемента (использование array_reduce)
Нестандартный подход - использовать array_reduce для разбивки на части по условию.
$numbers = [1,2,3,4,5,6,7,8,9,10];
$chunkSize = 3;
$chunks = array_reduce($numbers, function($carry, $item) use ($chunkSize) {
$lastIndex = count($carry) - 1;
if ($lastIndex < 0 || count($carry[$lastIndex]) >= $chunkSize) {
$carry[] = [];
$lastIndex++;
}
$carry[$lastIndex][] = $item;
return $carry;
}, []);
print_r($chunks);
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 4
[1] => 5
[2] => 6
)
[2] => Array
(
[0] => 7
[1] => 8
[2] => 9
)
[3] => Array
(
[0] => 10
)
)
Такой вариант может быть полезен при функциональном стиле программирования.