php array_chunk具有平衡的元素数量

时间:2014-04-17 16:06:40

标签: php arrays chunks

我需要将一个数组拆分成几个块,每个块都有相同数量的元素(甚至在不同的块中重复)在输出中平衡

所以,例如,从这样的数组开始:

$input = array(1,2,3,4,5,6,7,8,9,10,11);

我正在尝试开发一个接受输入数组的函数以及每个块上预期的元素数。例如,[ balanced_chunk($ input,3)]

应该让我

0 => array(1,2,3)
1 => array(4,5,6)
2 => array(6,7,8)         #-- Value 6 is repeated
3 => array(9,10,11)

只要[ balanced_chunk($ input,5)]

应该让我

0 => array(1,2,3,4,5)
1 => array(4,5,6,7,8)     #-- Value 4,5 are repeated
2 => array(7,8,9,10,11)   #-- Value 7,8 are repeated

等等

开始我已经开发了这样的功能

function balanced_chunk($input, $size) {
    $step = ceil(count($input) / $size);
    $chunks = range(0, count($input), count($input) / $step);
    reset($chunks);
    while (list(,$start) = each($chunks)) {
            $start = (fmod($start, 1) <= 0.5 ? floor($start) : ceil($start));
            $clist[] = array_slice($input, $start, $size, true);
    }
    return($clist);
}

但是由于我错过的一个原因,它得到了我的输出:

[0] => Array (1,2,3,4,5)
[1] => Array (5,6,7,8,9)     #-- this element should instead start from 4...
[2] => Array (8,9,10,11)     #-- last element contains only 4 value

只是为了更好的例子考虑输入数组     [a,b,c,d,e,f,g,h,i,l,m,n,o,p]

具有5个元素的平衡块必须是

[ a,b,c,d,e ]
          [ f,g,h,i,l ]
                  [ l,m,n,o,p ] #-- letter 'l' is repeated twice on 3rd result

或(作为有效的替代方案)

[ a,b,c,d,e ] 
        [ e,f,g,h,i ]           #-- letter 'e' is repeated twice on 2nd result
                    [ l,m,n,o,p ]

具有8个元素的平衡块必须是

[ a,b,c,d,e,f,g,h ] 
            [ g,h,i,l,m,n,o,p ]  #-- letter 'g','h' are repeated twice

我被困了!经过myselft的几次试验后,我无法找到解决这个问题的方法。

2 个答案:

答案 0 :(得分:1)

你现在可能已经转向了其他事情!但这是我这样做的方式。

function balanced_chunk($input, $size)
{
    $len = count($input);
    $chunkSize = ceil($len / $size);
    $o = [];
    $i = 1;
    $k = 0;
    foreach ($input as $elem)
    {
        $o[$k][$i] = $elem;
        $k = ($i % $chunkSize == 0) ? $k+1 : $k;
        $i++;
    }
    return $o;
}

答案 1 :(得分:0)

目前,等待找到一个更聪明的&#34;方法我找到了这个解决方案:

function balanced_chunk($input, $size) {
    $chunks   = ceil(count($input) / $size);
    $step     = count($input) / $chunks;
    $chunklist = array();
    for ($i = 0; $i < count($input); $i += $step) {
        $chunk = array_slice($input, floor($i), $size);
        if (count($chunk) < $size)  $chunk = array_slice($input, $size * -1, $size, true);
        $chunklist[] = $chunk;
    }
    return($chunklist);
}

这意味着例如...... Ex#1:11个元素分为3个块:

$split = balanced_chunk(range(1, 11), 3));
/*
[ 1,2,3 ]
    [ 3,4,5 ][ 6,7,8 ][ 9,10,11 ]

In such case the fx needs to be better tuned as a better balanced output
has instead to be

[ 1,2,3 ][ 4,5,6 ]
             [ 6,7,8 ][ 9,10,11 ]
*/

Ex#2:11个元素分为4个块:

$split = balanced_chunk(range(1, 11), 4));
/*
[ 1,2,3,4 ]
      [ 4,5,6,7 ][ 8,9,10,11 ]

In such case the given output is exactly comparable with the alternative

[ 1,2,3,4 ][ 5,6,7,8 ]
                 [ 8,9,10,11 ]
*/

Ex#3:11个元素分为5个块:

$split = balanced_chunk(range(1, 11), 5));
/*
[ 1,2,3,4,5 ]
      [ 4,5,6,7,8 ]
            [ 7,8,9,10,11 ]
*/

Ex#4:11个元素分为7个块:

$split = balanced_chunk(range(1, 11), 7));
/*
[ 1,2,3,4,5,6,7 ]
        [ 5,6,7,8,9,10,11 ]
*/

我欢迎提出改进建议或建议。