You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP按指定间隔合并两个数组的功能实现需求

嘿,我来帮你实现这个array_merge_interval函数!结合PHP的数组特性和简单的循环逻辑,我们可以写出清晰且符合需求的代码,避免复杂的嵌套循环。

需求回顾

我们需要实现一个函数array_merge_interval($arr1, $arr2, $x, $y),按照以下规则合并两个数组:

  • 循环执行:从$arr1取$x个元素(元素不足时从头循环取),再从$arr2取$y个元素(同样循环取)。
  • 停止条件:当所有需要取的元素都已包含在结果中——即如果$x>0则$arr1的所有元素都要被包含;如果$y>0则$arr2的所有元素都要被包含;若某数组不需要取元素(对应参数为0),则无需包含其元素。

实现代码

function array_merge_interval(array $arr1, array $arr2, int $x, int $y): array
{
    $result = [];
    
    // 处理边界情况:都不取元素
    if ($x === 0 && $y === 0) {
        return $result;
    }
    
    $count1 = count($arr1);
    $count2 = count($arr2);
    
    // 标记是否需要收集对应数组的所有元素
    $needCollect1 = $x > 0;
    $needCollect2 = $y > 0;
    
    // 用翻转数组来跟踪已收集的元素(键为元素,值用于标记)
    $collected1 = $needCollect1 ? array_flip($arr1) : [];
    $collected2 = $needCollect2 ? array_flip($arr2) : [];
    
    $remaining1 = count($collected1); // 剩余需要收集的arr1元素数量
    $remaining2 = count($collected2); // 剩余需要收集的arr2元素数量
    
    $index1 = 0;
    $index2 = 0;
    
    // 循环直到所有需要收集的元素都已收集完成
    while ($remaining1 > 0 || $remaining2 > 0) {
        // 从arr1取x个元素
        for ($i = 0; $i < $x && ($remaining1 > 0 || $remaining2 > 0); $i++) {
            if ($count1 === 0) break; // 空数组直接跳过
            
            $element = $arr1[$index1 % $count1];
            $result[] = $element;
            
            // 如果该元素还未被收集,标记为已收集
            if ($needCollect1 && isset($collected1[$element])) {
                unset($collected1[$element]);
                $remaining1--;
            }
            
            $index1++;
            
            // 检查是否所有需要收集的元素都已完成,是的话直接跳出所有循环
            if ($remaining1 === 0 && $remaining2 === 0) {
                break 2;
            }
        }
        
        // 从arr2取y个元素
        for ($i = 0; $i < $y && ($remaining1 > 0 || $remaining2 > 0); $i++) {
            if ($count2 === 0) break; // 空数组直接跳过
            
            $element = $arr2[$index2 % $count2];
            $result[] = $element;
            
            // 如果该元素还未被收集,标记为已收集
            if ($needCollect2 && isset($collected2[$element])) {
                unset($collected2[$element]);
                $remaining2--;
            }
            
            $index2++;
            
            // 检查是否所有需要收集的元素都已完成,是的话直接跳出所有循环
            if ($remaining1 === 0 && $remaining2 === 0) {
                break 2;
            }
        }
    }
    
    return $result;
}

代码关键点说明

  1. 边界处理:先处理$x和$y都为0的情况,直接返回空数组;同时处理空输入数组的情况,避免取模错误。
  2. 收集跟踪:用array_flip将原数组转为元素为键的数组,这样可以快速判断元素是否已被收集(isset操作是O(1)),并通过remaining1和remaining2跟踪剩余需要收集的元素数量。
  3. 循环取元素:通过$index % count($arr)的方式实现循环取数,不需要额外复制数组,简洁高效。
  4. 停止条件:每次添加元素后检查是否所有需要收集的元素都已完成,一旦完成直接跳出所有循环,避免不必要的迭代。

测试示例

我们来验证你给出的几个示例:

// 示例1:2个A、1个B循环
$arrA = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];
$arrB = [1, 2, 3, 4];
print_r(array_merge_interval($arrA, $arrB, 2, 1));
// 输出:Array ( [0] => A [1] => B [2] => 1 [3] => C [4] => D [5] => 2 [6] => E [7] => F [8] => 3 [9] => G [10] => H [11] => 4 )

// 示例2:2个B、1个A循环
print_r(array_merge_interval($arrB, $arrA, 2, 1));
// 输出:Array ( [0] => 1 [1] => 2 [2] => A [3] => 3 [4] => 4 [5] => B [6] => 1 [7] => 2 [8] => C [9] => 3 [10] => 4 [11] => D [12] => 1 [13] => 2 [14] => E [15] => 3 [16] => 4 [17] => F [18] => 1 [19] => 2 [20] => G [21] => 3 [22] => 4 [23] => H )

// 示例3:6个B、0个A
print_r(array_merge_interval($arrB, $arrA, 6, 0));
// 输出:Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )

// 示例4:20个A、3个B
print_r(array_merge_interval($arrA, $arrB, 20, 3));
// 输出与你给出的结果完全一致

内容的提问来源于stack exchange,提问作者powerbuoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:23:17