Как разделить два массива поровну в 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]
]
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
7
0
723
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Фрагмент кода ниже делает именно то, что вы хотите. Он вычисляет максимальную длину результирующих внутренних массивов (в вашем случае это 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 && $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++];
    }
}

Хороший ответ, но лучше добавить объяснение логики вашего кода :)

Alon Eitan 09.04.2019 20:28

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

GregorMohorko 09.04.2019 20:29

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

Kamikaze 09.04.2019 22:21

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

Kamikaze 09.05.2019 04:47
Ответ принят как подходящий

Другой способ, используя только 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
        )

)

Очень хорошее использование оператора модуля там. Даже не подумал об этом

Miroslav Glamuzina 09.04.2019 20:39

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

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

Результат:

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
        )

)

Другие вопросы по теме