Как разделить два массива поровну в PHP?

#php

#php

Вопрос:

Я пытаюсь разделить массивы поровну из двух наборов массивов

Например:

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

Что я пробовал:

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

Я ожидаю получить результат:

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

но фактический результат, который я получаю, это :

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

Ответ №1:

Другой способ с использованием всего 1 цикла (комментарии в коде)…

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

Вывод…

 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
        )

)
  

Комментарии:

1. Там очень хорошо используется оператор modulus. Даже не рассматривал это

Ответ №2:

Приведенный ниже фрагмент кода делает именно то, что вы хотите. Он вычисляет максимальную длину результирующих внутренних массивов (которая в вашем случае является 13/5 1=3 ) путем деления длины 2-го массива на длину 1-го массива. Затем для каждого элемента в 1-м массиве он изменяется от 0 до максимальной длины и добавляет элемент из 2-го массива в этой позиции в результирующий массив. В случае, если позиция выходит за границы, внутренний цикл for завершается.

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

Приведенный выше код выдает:

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

И если вы хотите получить такой результат:

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

… тогда этот код сделает это (основное отличие заключается в получении позиции и определении того, когда прерывать внутренний цикл):

 $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 amp;amp; $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  ];
    }
}
  

Комментарии:

1. Хороший ответ, но лучше добавить объяснение логики, лежащей в основе вашего кода 🙂

2. Я пытаюсь, я просто не знаю, как это объяснить. Дайте мне минуту. 😀

3. Спасибо за ответ и объяснение!

4. что делать, если порядок такой: a => [1,2,3] , b => [4,5,6] , c => [7,8,9] , d => [10,11] , e => [12,13] , какую часть кода нужно изменить? Спасибо

Ответ №3:

Другой подход:

 $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=>amp;$v){
        if(!isset($arr2[$i])) break;
        $v[] = $arr2[$i];
        $i  ;
    } 
} 
print_r($res);
  

Результат:

 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
        )

)