甚至跨列分布PHP数组

时间:2015-10-16 14:32:07

标签: php

所以,我想在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]]

2 个答案:

答案 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++; 
    }
}