Я пытаюсь разделить массивы поровну из двух наборов массивов
Например:
$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]
]






Фрагмент кода ниже делает именно то, что вы хотите. Он вычисляет максимальную длину результирующих внутренних массивов (в вашем случае это 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++];
}
}
Я пытаюсь, я просто не знаю, как это объяснить. Дай мне минуту. :D
Спасибо за ответ и объяснение!
как насчет такого порядка: a => [1,2,3], b => [4,5,6], c => [7,8,9], d => [10,11], e => [12,13], какую часть кода нужно изменить? Спасибо
Другой способ, используя только 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
)
)
Очень хорошее использование оператора модуля там. Даже не подумал об этом
Другой подход:
$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
)
)
Хороший ответ, но лучше добавить объяснение логики вашего кода :)