23

I know that array_chunk() allows to split an array into several chunks, but the number of chunks changes according to the number of elements. What I need is to always split the array into a specific number of arrays like 4 arrays for example.

The following code splits the array into 3 chunks, two chunks with 2 elements each and 1 chunk with 1 element. What I would like is to split the array always into 4 chunks, no matter the number of total elements that the array has, but always trying to divide the elements evenly in the chunks like the array_chunck function does. How can I accomplish this? Is there any PHP function for this?

$input_array = array('a', 'b', 'c', 'd', 'e');
print_r(array_chunk($input_array, 2));
print_r(array_chunk($input_array, 2, true));

Thank you.

omarqe
  • 59
  • 12
SnitramSD
  • 1,169
  • 3
  • 10
  • 18
  • Possible duplicate of [Split an Array into N Arrays - PHP](https://stackoverflow.com/questions/15579702/split-an-array-into-n-arrays-php) – mickmackusa Nov 03 '18 at 14:42

7 Answers7

56

You can try

$input_array = array(
        'a',
        'b',
        'c',
        'd',
        'e'
);

print_r(partition($input_array, 4));

Output

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

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

    [2] => Array
        (
            [0] => d
        )

    [3] => Array
        (
            [0] => e
        )

)

Function Used

/**
 * 
 * @param Array $list
 * @param int $p
 * @return multitype:multitype:
 * @link http://www.php.net/manual/en/function.array-chunk.php#75022
 */
function partition(Array $list, $p) {
    $listlen = count($list);
    $partlen = floor($listlen / $p);
    $partrem = $listlen % $p;
    $partition = array();
    $mark = 0;
    for($px = 0; $px < $p; $px ++) {
        $incr = ($px < $partrem) ? $partlen + 1 : $partlen;
        $partition[$px] = array_slice($list, $mark, $incr);
        $mark += $incr;
    }
    return $partition;
}
Milap
  • 6,915
  • 8
  • 26
  • 46
Baba
  • 94,024
  • 28
  • 166
  • 217
  • @Baba Very nice solution. :) I noticed a trailing closing bracket in your function. Unfortunately I cannot edit this mistake due to the minimum character limit. Just FYI – Demnogonis Dec 07 '15 at 17:37
  • Damn this is useful! Some comments would be nice to help understand what's going on, but otherwise this is just fantastic! – Alex McCabe Jun 15 '16 at 10:15
8

So many complex answers here. I'll post my simple solution :)

function splitMyArray(array $input_array, int $size, $preserve_keys = null): array
{
    $nr = (int)ceil(count($input_array) / $size);

    if ($nr > 0) {
        return array_chunk($input_array, $nr, $preserve_keys);
    }

    return $input_array;
}

Usage:

$newArray = splitMyArray($my_array, 3);

More details here: https://zerowp.com/split-php-array-in-x-equal-number-of-elements/

Andrei Surdu
  • 2,281
  • 3
  • 23
  • 32
5

Divide the size of the array with the number of chunks you want and supply that as the size of each chunk.

function array_chunks_fixed($input_array, $chunks=3 /*Default chunk size 3*/) {
    if (sizeof($input_array) > 0) {        
        return array_chunk($input_array, intval(ceil(sizeof($input_array) / $chunks)));
    }

    return array();
}

And call it like this:

array_chunks_fixed($myarray, 2); //override the default number of '3'
Si8
  • 9,141
  • 22
  • 109
  • 221
Jakob Pogulis
  • 1,150
  • 2
  • 9
  • 19
  • Thank you. But using that code if I have an array with 5 elements and I want to divide into 4 chuncks I get 5 chuncks instead of 4. Maybe I can always merge the last two arrays? – SnitramSD Mar 30 '13 at 20:32
  • 1
    use [`ceil`](http://php.net/manual/en/function.ceil.php) instead of `intval` - you want to ensure you always round up. – Emissary Mar 30 '13 at 20:33
  • Thank you. Using 3 chuncks works but when I try to get 4 chuncks from an array with 5 elements I always get 3 chuncks. I also tried to change intval to ceil. – SnitramSD Mar 30 '13 at 20:38
  • The problem with 4 chunks from an array that is 5 elements big is that the last chunk of array_chunk(..) is guaranteed to be of the same size or smaller than the previous chunks. In this case you would need one of the chunks to be bigger than the other. It could be accomplished by checking the size of the result and if it's bigger than $chunks, merge two of the chunks. – Jakob Pogulis Mar 30 '13 at 20:46
1

This what i write and work well print_r(array_divide($input,3));

function array_divide($array, $segmentCount) {
    $dataCount = count($array);
    if ($dataCount == 0) return false;
    $segmentLimit = 1;
    //if($segmentCount > $segmentLimit)
      //  $segmentLimit = $segmentCount;
    $outputArray = array();
    $i = 0;
    while($dataCount >= $segmentLimit) {

        if( $segmentCount  == $i)
            $i = 0;
        if(!array_key_exists($i, $outputArray))
            $outputArray[$i] = array();
        $outputArray[$i][] =  array_splice($array,0,$segmentLimit)[0] ;
        $dataCount = count($array);



       $i++;
    }
    if($dataCount > 0) $outputArray[] = $array;

    return $outputArray;
}
Alireza
  • 1,706
  • 16
  • 23
1

Another implementation similar to @Baba's partition() function.

// http://php.net/manual/en/function.array-slice.php#94138
// split the given array into n number of pieces 
function array_split($array, $pieces=2) 
{   
    if ($pieces < 2) 
        return array($array); 
    $newCount = ceil(count($array)/$pieces); 
    $a = array_slice($array, 0, $newCount); 
    $b = array_split(array_slice($array, $newCount), $pieces-1); 
    return array_merge(array($a),$b); 
} 

// Examples: 
$a = array(1,2,3,4,5,6,7,8,9,10); 
array_split($a, 2);    // array(array(1,2,3,4,5), array(6,7,8,9,10)) 
array_split($a, 3);    // array(array(1,2,3,4), array(5,6,7), array(8,9,10)) 
array_split($a, 4);    // array(array(1,2,3), array(4,5,6), array(7,8), array(9,10)) 
Jamie Chong
  • 832
  • 9
  • 13
0

This should work:

function getChunks(array $array, $chunks)
{

  if (count($array) < $chunks)
  {
    return array_chunk($array, 1);
  }

  $new_array = array();

  for ($i = 0, $n = floor(count($array) / $chunks); $i < $chunks; ++$i)
  {

    $slice = $i == $chunks - 1 ? array_slice($array, $i * $n) : array_slice($array, $i * $n, $n);

    $new_array[] = $slice;

  }

  return $new_array;

}

$input_array = array('a', 'b', 'c', 'd', 'e');

echo '<pre>' . print_r(getChunks($input_array, 4), TRUE) . '</pre>';
Michael
  • 11,912
  • 6
  • 49
  • 64
0

If someone is looking for a solution to divide the super array into smaller number of separate arrays.

$count = count($appArray); //$appArray contains all elements
$repoCount = 3; //No. of parts to divide

$n = floor($count/$repoCount);
$rem = $count % $repoCount;
$j=1;

while($j <= $repoCount){

   ${"arr_" . $j} = array();
   $j++;

}

$j=0;
$k=1;

for($i=0; $i < $count; $i++){

    if($j < $n){

        array_push(${"arr_" . $k}, $appArray[$i]);
        $j++;

    }
    else if($k < $repoCount){

        $j=0;
        $k++;
        --$i;

    }
    if($i >= ($count-$rem)){

        $k=1;

        for($j=0; $j < $rem; $j++, $i++, $k++){

            array_push(${"arr_" . $k},$appArray[$i]);

        }
        break;
    }
}
Sarthak Singhal
  • 665
  • 2
  • 10
  • 26