我要合并两个数组,以便首先插入数组A的前X个元素,然后一次又一次插入数组B的Y个元素,直到新数组包含两个数组中的所有元素。如果数组中的元素数量没有加起来,则应从数组的开头重新开始合并。
类似这样的东西:
<?php
$arrA = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];
$arrB = [1, 2, 3, 4];
# Print 2A 1B 2A 1B etc until no element is missing from the new array - as soon as new array contains all elements break
array_merge_interval($arrA, $arrB, 2, 1);
['A', 'B', 1, 'C', 'D', 2, 'E', 'F', 3, 'G', 'H', 4]
# Print 2B 1A 2B 1A etc until no element is missing from the new array - as soon as new array contains all elements break
array_merge_interval($arrB, $arrA, 2, 1);
[1, 2, 'A', 3, 4, 'B', 1, 2, 'C', 3, 4, 'D', 1, 2, 'E', 3, 4, 'F', 1, 2, 'G', 3, 4, 'H']
# Print 6B 0A etc until no element is missing from the new array - as soon as new array contains all elements break
array_merge_interval($arrB, $arrA, 6, 0);
[1, 2, 3, 4]
# Print 20A 3B etc until no element is missing from the new array - as soon as new array contains all elements break
array_merge_interval($arrA, $arrB, 20, 3);
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 1, 2, 3, 'E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 4]
我已经尝试过使用嵌套的for(每个)循环进行许多复杂的解决方案,但是我非常不满意(并且还没有完成),所以我希望有人可以使用一些未知的数组函数想出一些聪明的东西?>
答案 0 :(得分:3)
您可以使用此功能使其完全适合您的情况,
function array_merge_interval($a, $b, $aLength, $bLength)
{
$i = 0;
$k = 0;
$temp = [];
$flag = '';
if (!$bLength || !$aLength) {
return ((!$bLength && !$aLength) ? [] : (!$bLength ? $a : $b));
}
while (true) {
$j = 0;
while ($j != $aLength) {
$j++;
if ($i < count($a)) {
$temp[] = $a[$i];
$i++;
} else {
$i = 0;
$temp[] = $a[$i];
$i++;
continue;
}
}
$l = 0;
while ($l < $bLength) {
if ($k < count($b)) {
$temp[] = $b[$k];
$k++;
}
$l++;
}
if ($bLength == 0 || $flag == 'warning') {
break;
}
if ($b[$k] == $b[count($b) - 1]) {
$flag = 'warning';
}
}
return $temp;
}
在演示中,我显示了您期望的所有输出。
根据我的观察,{$ {1}}元素会重复自身直到$a
,直到$ b元素不会完成为止。
Demo。
答案 1 :(得分:2)
您可以使用这对功能:
function array_get_chunk($a, $size, &$i, &$leftOver) {
do {
$result[] = $a[$i % count($a)];
$i++;
if ($i <= count($a)) $leftOver--;
} while ($i % $size && $leftOver);
return $result;
}
function array_merge_interval($a, $b, $sizeA, $sizeB) {
if (!$sizeA && !$sizeB) return [];
if (!$sizeA) return $b;
if (!$sizeB) return $a;
$i = $j = 0;
$result = [];
$leftOver = count($a) + count($b);
do {
array_push($result, ...array_get_chunk($a, $sizeA, $i, $leftOver));
if ($leftOver) array_push($result, ...array_get_chunk($b, $sizeB, $j, $leftOver));
} while ($leftOver);
return $result;
}
array_get_chunk
函数是一个辅助函数。它需要一个数组,块大小,块应开始的偏移量以及允许访问的未访问元素的最大数量。
最后两个参数由引用传递,因为它们由函数更新。偏移量$i
将增加并且可能会超出数组的大小,因此将应用模(%
)将其映射到有效的数组索引。仅当该索引确实在范围内(不取模)时,我们才认为它是数组元素的 first 访问,因此只有$leftOver
减少。
一旦生成了完整的块,或者$leftOver
变量达到0,我们就会将该块返回给调用方。
主要功能array_merge_interval
首先检查一些简单的边界情况,其中一个或两个大小均为零。然后,将$leftOver
变量设置为两个数组中的元素总数。这样可以确保在至少收集完所有元素一次后,该过程将停止。
该循环为两个数组中的每个数组调用helper函数,并使用array_push
(和splash运算符)将返回的块添加到最终结果中。这一直持续到$leftOver
达到0。
答案 2 :(得分:1)
在ArrayIterator帮助下看起来会更好:
<?php
$arrA = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];
$arrB = [1, 2, 3, 4];
var_dump(array_merge_interval($arrA, $arrB, 2, 1) == ['A', 'B', 1, 'C', 'D', 2, 'E', 'F', 3, 'G', 'H', 4]);
var_dump(array_merge_interval($arrB, $arrA, 2, 1) == [1, 2, 'A', 3, 4, 'B', 1, 2, 'C', 3, 4, 'D', 1, 2, 'E', 3, 4, 'F', 1, 2, 'G', 3, 4, 'H']);
var_dump(array_merge_interval($arrB, $arrA, 6, 0) == [1, 2, 3, 4]);
var_dump(array_merge_interval($arrA, $arrB, 20, 3) == ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 1, 2, 3, 'E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 4]);
function array_merge_interval(array $arrA, array $arrB, int $sizeA, int $sizeB): array
{
$res = [];
$itA = new ArrayIterator($arrA);
$itB = new ArrayIterator($arrB);
$stopA = $sizeA <= 0;
$stopB = $sizeB <= 0;
while (!($stopA && $stopB)) {
$stopA = addItem($sizeA, $res, $itA, $stopB);
$stopB = addItem($sizeB, $res, $itB, $stopA);
}
return $res;
}
function addItem(int $size, array &$res, ArrayIterator $iterator, bool $stop): bool
{
if ($size <= 0) {
return true;
}
$flag = false;
for ($i = 0; $i < $size; $i++) {
$res[] = $iterator->current();
$iterator->next();
if (!$iterator->current()) {
$iterator->rewind();
if ($stop) {
return true;
}
$flag = true;
}
}
return $flag;
}