В этой статье рассмотрим, как равномерно разделить массив на указанное количество подмассивов (колонок) в PHP. Такой подход полезен, например, при создании многоколоночных списков, таблиц или распределении данных для визуального отображения.
Основная задача
Необходимо написать функцию, которая:
-
Принимает исходный массив и число, обозначающее количество подмассивов.
-
Распределяет элементы исходного массива между подмассивами максимально равномерно.
Простое решение
Рассмотрим базовую реализацию:
/**
* Разделяет массив на указанное количество подмассивов (колонок)
*
* @param array $originalArr Исходный массив
* @param int $countCols Количество подмассивов
* @return array Массив подмассивов
*/
function breakdown_column($originalArr, $countCols)
{
if (!is_array($originalArr) || $countCols <= 0) {
return [];
}
$countRows = ceil(count($originalArr) / $countCols);
$resultArr = [];
for ($col = 0; $col < $countCols; $col++) {
$offset = $col * $countRows;
$resultArr[$col] = array_slice($originalArr, $offset, $countRows);
}
return $resultArr;
}Как это работает?
-
Вычисляется размер каждого подмассива (
$countRows), округляя вверх. -
Элементы распределяются последовательно с помощью
array_slice().
Пример использования
$array = ['один', 'два', 'три', 'четыре', 'пять', 'шесть', 'семь', 'восемь', 'девять', 'десять'];
$result = breakdown_column($array, 3);
print_r($result);Вывод:
Array
(
[0] => Array
(
[0] => один
[1] => два
[2] => три
[3] => четыре
)
[1] => Array
(
[0] => пять
[1] => шесть
[2] => семь
[3] => восемь
)
[2] => Array
(
[0] => девять
[1] => десять
)
)Улучшенная версия
Базовая реализация имеет несколько ограничений. Улучшим её, добавив:
-
Поддержку ассоциативных массивов.
-
Возможность распределять элементы построчно (а не последовательно).
-
Контроль за сохранением ключей.
/**
* Разделяет массив на указанное количество подмассивов (колонок)
*
* @param array $originalArr Исходный массив
* @param int $countCols Количество подмассивов
* @param bool $rowwise Если true, распределяет элементы построчно
* @param bool $preserveKeys Сохранять ли ключи исходного массива
* @return array Массив подмассивов
*/
function breakdown_column($originalArr, $countCols, $rowwise = false, $preserveKeys = false)
{
if (!is_array($originalArr) || $countCols <= 0) {
return [];
}
$resultArr = array_fill(0, $countCols, []);
if ($rowwise) {
// Построчное распределение
foreach ($originalArr as $key => $value) {
$col = array_key_first($resultArr);
if ($preserveKeys) {
$resultArr[$col][$key] = $value;
} else {
$resultArr[$col][] = $value;
}
// Перемещаем заполненную колонку в конец
$resultArr[] = $resultArr[$col];
unset($resultArr[$col]);
}
} else {
// Последовательное распределение
$countRows = ceil(count($originalArr) / $countCols);
for ($col = 0; $col < $countCols; $col++) {
$offset = $col * $countRows;
$slice = array_slice($originalArr, $offset, $countRows, $preserveKeys);
$resultArr[$col] = $preserveKeys ? $slice : array_values($slice);
}
}
return array_values($resultArr);
}Примеры работы улучшенной версии
1. Последовательное распределение
$array = ['a', 'b', 'c', 'd', 'e', 'f'];
$result = breakdown_column($array, 2);
print_r($result);Вывод:
Array
(
[0] => Array
(
[0] => a
[1] => b
[2] => c
)
[1] => Array
(
[0] => d
[1] => e
[2] => f
)
)2. Построчное распределение
$array = ['a', 'b', 'c', 'd', 'e', 'f'];
$result = breakdown_column($array, 2, true);
print_r($result);Вывод:
Array
(
[0] => Array
(
[0] => a
[1] => c
[2] => e
)
[1] => Array
(
[0] => b
[1] => d
[2] => f
)
)3. Работа с ассоциативным массивом
$array = ['k1' => 'a', 'k2' => 'b', 'k3' => 'c'];
$result = breakdown_column($array, 2, false, true);
print_r($result);Вывод:
Array
(
[0] => Array
(
[k1] => a
[k2] => b
)
[1] => Array
(
[k3] => c
)
)Заключение
Функция breakdown_column позволяет гибко разделять массив на подмассивы. Базовая версия подходит для простых случаев, а улучшенная поддерживает:
-
Разные стратегии распределения (последовательно или построчно).
-
Сохранение или сброс ключей.
-
Обработку ассоциативных массивов.
Этот подход можно использовать для вёрстки многоколоночных списков, формирования таблиц или балансировки нагрузки при обработке данных.