26

我有一个包含 18 个值的数组:

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

我想将此数组拆分为 12 个不同的数组,因此它应如下所示:

array(
    0 => array('a', 'b'),
    1 => array('c', 'd'),
    2 => array('e', 'f'),
    3 => array('g', 'h'),
    4 => array('i', 'j'),
    5 => array('k', 'l'),
    6 => array('m'),
    7 => array('n'),
    8 => array('o'),
    9 => array('p'),
   10 => array('q'),
   11 => array('r')
)

我的功能似乎不起作用

function array_split($array, $parts){
    return array_chunk($array, ceil(count($array) / $parts));
}

$result = array_split($array, 12);

因为我得到 9 个不同的数组而不是 12 个。它会返回

array(
    0 => array('a', 'b'),
    1 => array('c', 'd'),
    2 => array('e', 'f'),
    3 => array('g', 'h'),
    4 => array('i', 'j'),
    5 => array('k', 'l'),
    6 => array('m', 'n'),
    7 => array('o', 'p'),
    8 => array('q', 'r')
)

我该怎么做呢?谢谢。

4

11 回答 11

36

这个简单的功能会为你工作:

用法

$array = range("a", "r"); // same as your array
print_r(alternate_chunck($array,12));

输出

Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
        )

    [1] => Array
        (
            [0] => c
            [1] => d
        )

    [2] => Array
        (
            [0] => e
            [1] => f
        )

    [3] => Array
        (
            [0] => g
            [1] => h
        )

    [4] => Array
        (
            [0] => i
            [1] => j
        )

    [5] => Array
        (
            [0] => k
            [1] => l
        )

    [6] => Array
        (
            [0] => m
        )

    [7] => Array
        (
            [0] => n
        )

    [8] => Array
        (
            [0] => o
        )

    [9] => Array
        (
            [0] => p
        )

    [10] => Array
        (
            [0] => q
        )

    [11] => Array
        (
            [0] => r
        )

)

更新上面可能对大多数情况没有用......这是另一种类型的块

$array = range("a", "r"); // same as your array
print_r(fill_chunck($array, 5));

输出

Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
            [2] => c
            [3] => d
        )

    [1] => Array
        (
            [0] => e
            [1] => f
            [2] => g
            [3] => h
        )

    [2] => Array
        (
            [0] => i
            [1] => j
            [2] => k
            [3] => l
        )

    [3] => Array
        (
            [0] => m
            [1] => n
            [2] => o
            [3] => p
        )

    [4] => Array
        (
            [0] => q
            [1] => r
        )

)

这将确保该组在任何时候都不会超过 5 个元素,而另一个则没有限制

使用的功能

function alternate_chunck($array, $parts) {
    $t = 0;
    $result = array();
    $max = ceil(count($array) / $parts);
    foreach(array_chunk($array, $max) as $v) {
        if ($t < $parts) {
            $result[] = $v;
        } else {
            foreach($v as $d) {
                $result[] = array($d);
            }
        }
        $t += count($v);
    }
    return $result;
}


function fill_chunck($array, $parts) {
    $t = 0;
    $result = array_fill(0, $parts - 1, array());
    $max = ceil(count($array) / $parts);
    foreach($array as $v) {
        count($result[$t]) >= $max and $t ++;
        $result[$t][] = $v;
    }
    return $result;
}
于 2013-05-02T18:44:00.287 回答
7

请允许我成为第一个提供基于数学的无环解决方案的人。

数学中的魔力在于确定元素的哪一部分属于第一组块,其中所有列都填充在每一行中,哪些元素属于第二组(如果该组甚至应该存在),除了最右边的所有列列已填满。

让我画出我在说什么。>标记两个分块数组之间的划分。

$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 |
                   -----

代码:(演示

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

如果您不介意迭代array_splice()调用,这会更简短,也许更容易理解(......也许不是):

代码:(演示

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));
于 2018-11-03T10:14:27.377 回答
2

您可以使用array_chunkandarray_merge来解决这个问题:

<?php 

$array = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r');
$chunked_arr = array_chunk($array,12);
$j = 0;
for($i = 0; $i < count($chunked_arr[0]); $i++){
    if(!($i % 2 == 0)){
        $first_combined[$j][$i % 2] = $chunked_arr[0][$i];
        $j++;
    } else {
    $first_combined[$j][$i % 2] = $chunked_arr[0][$i];
    }
}

$merged_array = array_merge($first_combined, $chunked_arr[1]); 

echo '<pre>';
print_r($merged_array);
 ?>

你会得到这样的结果:

Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
        )

    [1] => Array
        (
            [0] => c
            [1] => d
        )

    [2] => Array
        (
            [0] => e
            [1] => f
        )

    [3] => Array
        (
            [0] => g
            [1] => h
        )

    [4] => Array
        (
            [0] => i
            [1] => j
        )

    [5] => Array
        (
            [0] => k
            [1] => l
        )

    [6] => m
    [7] => n
    [8] => o
    [9] => p
    [10] => q
    [11] => r
)

这正是你想要的。

现场演示在这里>>

于 2013-05-03T10:10:10.630 回答
1

ceil(count($array) / $parts)会给出 2,所以每个数组都被 2 个项目填满,直到你没有 2 个项目。因此最后一个有 1 个项目。当您在数组中有大量数据时,这将起作用,但当您有少量数据时就不行了。

于 2013-03-22T21:08:41.857 回答
1

您所描述的不是 array_chunk 的用途。您应该使用array_slice()并自己计算要作为新数组结束的数组部分。(并使用 for 循环遍历您的原始数组)

更新:

一些可以帮助你的计算:

minimum_fill = floor(array_length / nr_buckets)
bigger_buckets_amount = array_length - (minimum_fill / nr_buckets)

填充桶的算法:遍历数组,用 填充第一bigger_buckets_amount数量的桶(minimum_fill + 1),用 填充其余的桶minimum_fill

于 2013-03-22T21:08:50.767 回答
1

编译它,看看它是否适合你:

<?php

$array = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm');

$sliceA = 0;
$sliceB = 2;

$final = array(array_slice($array, $sliceA, $sliceB));


for ($i=$sliceB; $i<sizeof($array); $i++)
{
    $final[$sliceB-1] = array($array[$i]);
    $sliceB++;
}

var_dump($final);
于 2013-03-22T22:14:35.927 回答
1
<?php
$array = range('a','r');
$length = array(2=>6,1=>6); // 2=>6 means -- first six elements of new array will have 2 elements each and then, 1=>6 means -- next six elements of new array will have 1 element each
$target = array(); // or use []  in PHP 5.4
foreach($length as $i=>$times) {
    while($times>0){
        $target[] = array_splice($array, 0, $i);
        $times--;
    }
}
print_r($target);
?>
于 2013-05-05T11:30:52.247 回答
1
<?php
function slotify($array, $length)
{
    // Create a placeholder array and calculate the number of items
    // needed per slot (think card dealing LtoR).
    for(
        $slots = array_fill(0, $length, 0), $count=count($array), $i=0;
        $i<$count;
        $slots[$i % $length]++, $i++
    );

    // Now just take slices of the original array
    // depending on the calculated slot number and place in our slots
    foreach($slots as $k => $n) {
        $slots[$k] = array_splice($array, 0, $n);
    }

    return $slots;
}

var_export(slotify(['a','b','c','d','e','f'], 4));

输出:

array (
  0 => 
  array (
    0 => 'a',
    1 => 'b',
  ),
  1 => 
  array (
    0 => 'c',
    1 => 'd',
  ),
  2 => 
  array (
    0 => 'e',
  ),
  3 => 
  array (
    0 => 'f',
  ),
)

$slots对于上面的示例,包含所需项目数量的中间数组如下所示:

array (
  0 => 2,
  1 => 2,
  2 => 1,
  3 => 1,
)

如果您研究中间数组的不同组合。您需要计算出块大小变化的边界点。我的解决方案倾向于以下,这几乎是 mickmacusa 的最终解决方案。但这需要理解问题。

function slotify($array, $length)
{
    $count      = count($array);
    $chunk_size = ceil($count/$length);
    $boundary   = $count % $length;

    if($boundary === 0)
        $boundary = $length;

    for($i=0; $i<$length; $i++) {
        if($i === $boundary)
            $chunk_size--;
        $result[$i] = array_splice($array, 0, $chunk_size);
    }

    return $result;
}

可以进行进一步的改进,切片可能比拼接更有效,如果您可以在整个阵列中均匀分布,您可以使用快捷方式。

于 2020-09-17T12:01:31.653 回答
0

这将为您做到!
在这里,我使用我的函数 smallify() 将一个包含 15 个元素的数组分解为 3 个数组,每个数组包含 5 个元素。

<?php

$bigArray = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);

echo ("<pre>");
print_r (smallify($bigArray, 3));
echo ("<pre/>");


function smallify($arr, $numberOfSlices){

  $sliceLength = sizeof($arr) /$numberOfSlices;
  for($i=1; $i<=$numberOfSlices; $i++){

       $arr1 = array_chunk($arr, $sliceLength*$i);
       return $arr1;
       unset($arr1);

   }

}
?>

结果

Array
(
[0] => Array
    (
        [0] => 1
        [1] => 2
        [2] => 3
        [3] => 4
        [4] => 5
    )

[1] => Array
    (
        [0] => 6
        [1] => 7
        [2] => 8
        [3] => 9
        [4] => 10
    )

[2] => Array
    (
        [0] => 11
        [1] => 12
        [2] => 13
        [3] => 14
        [4] => 15
    )

)
于 2015-09-29T08:55:00.927 回答
-1

我相信问题在于您在使用 array_chunk 时使用了 2 的大小。如果可能,这确保创建的每个新数组都包含两个项目。这会导致函数在您达到 10 时用完要放入新数组的变量。您可以在此处找到函数手册http://php.net/manual/en/function.array-chunk。 php 希望这有帮助

于 2013-05-05T19:33:50.620 回答
-1

您可以尝试使用以下简单功能吗?

$cols = array2cols($array,12);

function array2cols($array,$n){
    $groups = array();
    for($i=0;$i<$n;$i++){
        $groups[$i] = array();
    }
    $col = 0;
    foreach($array as $row){
        $groups[$col][] = $row;
        $col = ($col+1)%$n;
    }
    return $groups;
}
于 2019-12-01T09:43:18.240 回答