所以,我想在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]]
答案 0 :(得分:1)
您需要做的就是循环遍历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's full
}
$thisrow++;
}
这将是一个从左到右的均匀分布。但是你实际上想要一个看起来对称的均匀分布。所以在foreach循环中,你需要跟踪1.)如果你在最后一排三,和2.)如果有2个余数,让它跳过col2并推送到col3。你需要设置它才能玩它,...但你只是远离牛奶和蜂蜜的几个逻辑门。
答案 1 :(得分:0)
所以,我最终使用了这段代码:
$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++;
}
}