Итак, я хочу распределить равномерные списки по 3 столбцам. Списки не могут быть разбиты или переупорядочены.
На данный момент у меня есть 5 списков, каждый из которых содержит соответственно 4, 4, 6, 3 и 3 позиции.
Мой первоначальный подход:
$lists = [4,4,6,3,3];
$columns = 3;
$total_links = 20;
$items_per_column = ceil($total_links/$columns);
$current_column = 1;
$counter = 0;
$lists_by_column = [];
foreach ($lists as $total_items) {
$counter += $total_items;
$lists_by_column[$current_column][] = $total_items;
if ($counter > $current_column*$links_per_column) {
$current_column++;
}
}
Результаты в:
[
[4],
[4,6],
[3,3]
]
Но я хочу, чтобы это выглядело так:
[
[4,4],
[6],
[3,3]
]
Я хочу всегда иметь наименьшее возможное изменение длины между столбцами.
Другие примеры ожидаемых результатов:
[6,4,4,6]
=> [[6], [4,4], [6]]
[4,4,4,4,6]
=> [[4,4], [4,4], [6]]
[10,4,4,3,5]
=> [[10], [4,4], [3,5]]
[2,2,4,6,4,3,3,3]
=> [[2,2,4], [6,4], [3,3,3]]
Примерно то, что вам нужно сделать, это цикл над количеством столбцов в вашем foreach(). Это будет распространять их для вас.
$numrows = ceil(count($lists) / $columns);
$thisrow = 1;
foreach ($lists as $total_items) {
if($thisrow < $numrows){
for($i = 1; $i <= $columns; $i++){
$lists_by_column[$i][] = $total_items;
}
}else{
//this is the last row
//find out how many columns need to fit.
//1 column is easy, it goes in the first column
//2 columns is when you'll need to skip the middle one
//3 columns is easy because it full
}
$thisrow++;
}
Это будет равномерное распределение слева направо. Но на самом деле вы хотите изменить равномерное распределение, которое будет выглядеть симметрично для глаз. Таким образом, в цикле foreach вам нужно будет отслеживать 1.), если вы находитесь в последней строке из трех, и 2.), если есть 2 остатка, чтобы он пропустил col2 и нажал вместо col3. Вам нужно будет настроить это, чтобы иметь возможность поиграть с ним... но вы всего лишь пара логических ворот от земли молока и меда.
if you're on the last row of three
Итак, я использовал этот код:
$lists = [4,4,6,3,3];
$columns = 3;
$total_links = 20;
$items_per_column = ceil($total_links/$columns);
$current_column = 1;
$lists_by_column = [];
for ($i = 0; $i < count($lists); $i++) {
$total = $lists[$i];
$lists_by_column[$current_column][] = $lists[$i];
//Loop until reaching the end of the column
while ($total < $items_per_column && $i+1 < count($lists)) {
if ($total + $lists[$i+1] > $items_per_column) {
break;
}
$i++;
$total += $lists[$i];
$lists_by_column[$current_column][] = $lists[$i];
}
//When exiting the loop the last time we need another break
if (!isset($lists[$i+1])) {break;}
//If the last item goes onto the next column
if (abs($total - $items_per_column) < abs($total + $lists[$i+1] - $items_per_column)) {
$current_column++;
//If the last item goes onto the current column
} else if ($total + $lists[$i+1] > $items_per_column) {
$i++;
$lists_by_column[$current_column][] = $lists[$i];
$current_column++;
}
}
I want the first column to contain the first 2 lists, the second, the third list and the last must contain the last 2 lists.
Другое дело, почему ваш ожидаемый результат10, 4, 4, 3, 5
отличается от4, 4, 4, 4, 6
?