Home » Php » How to divide two arrays equally in PHP?

How to divide two arrays equally in PHP?

Posted by: admin July 12, 2020 Leave a comment

Questions:

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]
]
How to&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
        )

)

Answer:

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++];
    }
}

Answer:

A different approach:

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

$i =0;
$res = array_fill_keys($arr1, []);
while(isset($arr2[$i])){
    foreach($res as $k=>&$v){
        if(!isset($arr2[$i])) break;
        $v[] = $arr2[$i];
        $i++;
    } 
} 
print_r($res);

Result:

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
        )

)