Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to divide two arrays equally in PHP?

Tags:

php

I'm trying to divide arrays equally from two sets of arrays

For example:

$arr1 = [a,b,c,d,e];
$arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];

What I have tried:

$arr1 = [a,b,c,d,e];
$arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];
$arrRes = [];

$key = 0;

for($i=0;$i<count($arr1);$i++){
  $arrRes[$arr1[$key]][] = $arr2[$i];
  $key++;
}

$key2 = 0;
for($k=0;$k<count($arr1);$k++){
  $arrRes[$arr1[$key2]][] = $arr2[$key];
  $key++;
  $key2++;
  if ($key == count($arr2)) {
    break;
  }
}

I expect to get the output:

[
   "a" => [1,6,11],
   "b" => [2,7,12],
   "c" => [3,8,13],
   "d" => [4,9],
   "e" => [5,10]
]

but the actual output I get is :

[
   "a" => [1,6],
   "b" => [2,7],
   "c" => [3,8],
   "d" => [4,9],
   "e" => [5,10]
]
like image 330
Kamikaze Avatar asked Apr 09 '19 18:04

Kamikaze


People also ask

How to divide two arrays in php?

PHP | array_chunk() Function The array_chunk() function is an inbuilt function in PHP which is used to split an array into parts or chunks of given size depending upon the parameters passed to the function. The last chunk may contain fewer elements than the desired size of the chunk.

Which function is used to divide an array into smaller evenly size arrays?

The array_chunk() function splits an array into chunks of new arrays.

Which construct can be used to split an array into a number of values?

An array can be split into the number of chunks. A built-in function array_chunk() can be used to split the array into multiple arrays with a defined number of elements.


2 Answers

Another way with just using 1 loop (comments in code)...

$arr1 = ['a','b','c','d','e'];
$arr2 = [1,2,3,4,5,6,7,8,9,10,11,12,13];

// Create output array from the keys in $arr1 and an empty array
$arrRes = array_fill_keys($arr1, []);

$outElements = count($arr1);
// Loop over numbers
foreach ( $arr2 as $item => $value ) {
    // Add the value to the index based on the current
    // index and the corresponding array in $arr1.
    // Using $item%$outElements rolls the index over
    $arrRes[$arr1[$item%$outElements]][] = $value;
}
print_r($arrRes);

Output...

Array
(
    [a] => Array
        (
            [0] => 1
            [1] => 6
            [2] => 11
        )

    [b] => Array
        (
            [0] => 2
            [1] => 7
            [2] => 12
        )

    [c] => Array
        (
            [0] => 3
            [1] => 8
            [2] => 13
        )

    [d] => Array
        (
            [0] => 4
            [1] => 9
        )

    [e] => Array
        (
            [0] => 5
            [1] => 10
        )

)
like image 111
Nigel Ren Avatar answered Oct 15 '22 09:10

Nigel Ren


The code snippet bellow does exactly what you want. It calculates the max length of the resulting inner arrays (which in your case is 13/5+1=3) by dividing the length of the 2nd array with the length of the 1st array. Then, for each element in the 1st array, it goes from 0 to the max length and adds the element from the 2nd array at that position to the resulting array. In the case that the position is out of bounds, the inner for loop is exited.

$arr1 = ['a', 'b', 'c', 'd', 'e'];
$arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
$arrRes = [];
// create an empty result array of arrays
foreach($arr1 as $key){
    // the keys are the values from the 1st array
    $arrRes[$key] = [];
}
$maxLength = intval(count($arr2) / count($arr1)) + 1;
for($i = 0; $i < count($arr1); ++$i) {
    for($j = 0; $j < $maxLength; ++$j) {
        $pos = $j * count($arr1) + $i;
        if($pos >= count($arr2)) {
            break;
        }
        $arrRes[$arr1[$i]][] = $arr2[$pos];
    }
}

The above code produces:

[
   "a" => [1,6,11],
   "b" => [2,7,12],
   "c" => [3,8,13],
   "d" => [4,9],
   "e" => [5,10]
]

And if you want a result like this:

[
   "a" => [1,2,3],
   "b" => [4,5,6],
   "c" => [7,8,9],
   "d" => [10,11],
   "e" => [12,13]
]

... then this code will do this (the main difference is in getting the position and determining when to break the inner loop):

$arr1 = ['a', 'b', 'c', 'd', 'e'];
$arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
$arrRes = [];
foreach($arr1 as $key){
    $arrRes[$key] = [];
}
$maxLength = intval(count($arr2) / count($arr1)) + 1;
$pos = 0;
for($i = 0; $i < count($arr1); ++$i) {
    $arraysLeftAfter = count($arr1) - $i - 1;
    for($j = 0; $j < $maxLength && $pos < count($arr2); ++$j) {
        if($arraysLeftAfter > 0) {
            $elCountAfter = count($arr2) - $pos - 1;
            $myLengthAfter = ($j + 1);
            $maxLengthAfter = floor(($elCountAfter / $arraysLeftAfter) + 1);
            if($myLengthAfter > $maxLengthAfter) {
                break;
            }
        }
        $arrRes[$arr1[$i]][] = $arr2[$pos++];
    }
}
like image 34
GregorMohorko Avatar answered Oct 15 '22 07:10

GregorMohorko