Split an Array into N Arrays - PHP

前端 未结 11 1786
一向
一向 2020-12-05 07:05

I have an array of 18 values:

$array = array(\'a\', \'b\', \'c\', \'d\', \'e\', \'f\', \'g\', \'h\', \'i\', \'j\', \'k\', \'l\', \'m\', \'n\', \'o\', \'p\',          


        
11条回答
  •  半阙折子戏
    2020-12-05 08:02

    Allow me to be the first to offer a math-based, loopless solution.

    The magic in the math is determining which portion of elements belongs in the first set of chunks where all columns are filled in each row versus which elements belong in the second set (if the set should even exist) where all columns except the right-most column are filled.

    Let me draw what I'm talking about. The > marks the division between the two chunked arrays.

    $size = 9;        -------------    $size = 9;        -------------
    $maxRows = 4;   1 | A , B , C |    $maxRows = 3;     | A , B , C |
    $columns = 3;   > |-----------|    $columns = 3;   1 | D , E , F |
    $fullRows = 1;    | D , E |        $fullRows = 3;    | G , H , I |
                    2 | F , G |                        > -------------
                      | H , I |                        2      n/a
                      ---------
    
    
    $size = 18;        ---------    $size = 17;       -------------------------------------
    $maxRows = 12;     | A , B |    $maxRows = 2;   1 | A , B , C , D , E , F , G , H , I |
    $columns = 2;      | C , D |    $columns = 9;   > -------------------------------------
    $fullRows = 6;     | E , F |    $fullRows = 1;  2 | J , K , L , M , N , O , P , Q |
                     1 | G , H |                      ---------------------------------
                       | I , J |
                       | K , L |
                     > ---------
                       | M |
                       | N |
                       | O |
                     2 | P |
                       | Q |
                       | R |
                       -----
    

    Code: (Demo)

    function double_chunk($array, $maxRows) {
        $size = count($array);
        $columns = ceil($size / $maxRows);
        $lessOne = $columns - 1;
        $fullRows = $size - $lessOne * $maxRows;
        
        if ($fullRows == $maxRows) {
            return array_chunk($array, $fullRows);  // all columns have full rows, don't splice
        }
        return array_merge(
                   array_chunk(
                       array_splice($array, 0, $columns * $fullRows),  // extract first set to chunk
                       $columns
                   ),
                   array_chunk($array, $lessOne)   // chunk the leftovers
               );
    }
    var_export(double_chunk(range('a', 'i'), 3));
    

    If you don't mind the iterated array_splice() calls, this is more brief and perhaps easier to follow (...perhaps not):

    Code: (Demo)

    function custom_chunk($array, $maxRows) {
        $size = count($array);
        $columns = ceil($size / $maxRows);
        $lessOne = $columns - 1;
        $fullRows = $size - $lessOne * $maxRows;
        
        for ($i = 0; $i < $maxRows; ++$i) {
            $result[] = array_splice($array, 0, ($i < $fullRows ? $columns : $lessOne));
        }
        return $result;
    }
    var_export(custom_chunk(range('a', 'r'), 12));
    

提交回复
热议问题