【问题标题】:php array_chunk with balanced number of elements具有平衡数量的元素的php array_chunk
【发布时间】:2014-04-17 16:06:40
【问题描述】:

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

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

$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

我被困住了!经过我自己的几次尝试,我无法找到解决此类问题的方法。

【问题讨论】:

  • 你如何决定什么对由序列 1-11 组成的第二个数组有效? 6,7,8,9,10 在 8,9 和 10 都重复的情况下也有效吗? 5,6,7,8,9 怎么样,其中 5、8 和 9 在其他地方都重复(第一个数组中的 5 和第二个数组中的 8 和 9)?
  • 不准确,因为我的范围不会平衡序列。在您的示例中,我将拥有[1,2,3,4,5][6,7,8,9,10][7,8,9,10,11],这意味着第一个结果的 0 值与第二个结果相同,第二个结果的 4 个结果与最后一个结果相同。而“平衡”分布必须产生[1,2,3,4,5][4,5,6,7,8][7,8,9,10,11],其中 2 个值第一个结果与第二个结果相同,第二个结果的 2 个结果与第三个结果相同。
  • 非常有趣的挑战。这个从哪里来?为什么需要这个?
  • 我将使用更小的“子”矩阵 [n,m] 优化“父”矩阵 [ N,M ]。挑战在于计算覆盖整个“父”矩阵所需的较小矩阵的重复次数更少。首先,我假设将输入矩阵减少为(例如)75 个元素的简单水平数组,并用只有 10 个元素的“子数组”覆盖,但 [a] 可以重叠,并且在重叠的情况下覆盖必须在“父亲”数组的中间保持平衡。

标签: php arrays chunks


【解决方案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;
}

【讨论】:

    【解决方案2】:

    目前,等待找出“更智能”的方法,我找到了这个解决方案:

    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);
    }
    

    这意味着例如... 例如 #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 ]
    */
    

    我欢迎提出改进这一点的提示或建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-19
      • 2018-07-18
      • 2016-11-06
      • 2015-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-17
      相关资源
      最近更新 更多