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

递归函数无法终止:二维数组按指定列分组问题排查

问题分析与解决方案

为什么你的递归函数无法终止且重复执行?

你的递归逻辑有个关键漏洞:当找到拆分点并触发递归调用后,当前的for循环并没有停止执行。举个实际场景的例子:

  • 假设在索引x处发现第7列的值和x+1不同,你调用splitArray(fromArray: array, startIndex: x+1)处理后续元素;
  • 但递归返回后,原来的for循环会继续执行x += 1,接着检查x+1的元素,这会导致同一个拆分点被多次处理,甚至重复触发递归,最终函数无法按预期终止,还会出现重复执行的情况。

另外,你的函数目前没有任何收集子数组的逻辑,只是在做递归遍历,自然无法生成你需要的拆分结果。

优化方案:用迭代实现更清晰可靠

递归在这里其实是不必要的,用迭代的方式可以更直观地控制流程,也更容易避免循环和递归的冲突。下面是实现思路和代码:

实现思路

  1. 跳过索引0的元素,从索引1开始处理;
  2. 维护一个currentStart变量,记录当前子数组的起始索引;
  3. 遍历数组(从1到末尾),每次检查当前元素和下一个元素的第7列值:
    • 如果不同,就从currentStart到当前索引x切分子数组,加入结果集合;
    • 更新currentStart为x+1;
  4. 遍历结束后,别忘了把最后一段(从currentStart到数组末尾)也加入结果。

Swift 代码实现

static func splitArray(fromArray array: [[String]]) -> [[[String]]] {
    // 空数组或只有索引0的元素,直接返回空结果
    guard array.count > 1 else { return [] }
    // 提前检查所有元素的列数是否足够,避免越界错误
    guard array.allSatisfy({ $0.count > 7 }) else {
        fatalError("数组中存在元素的列数不足8列,无法访问第7列")
    }
    
    var result = [[[String]]]()
    var currentStart = 1
    
    for x in 1..<array.count {
        // 检查是否有下一个元素,且当前与下一个元素的第7列值不同
        if x + 1 < array.count && array[x][7] != array[x+1][7] {
            // 切分当前子数组并加入结果
            let subArray = Array(array[currentStart...x])
            result.append(subArray)
            currentStart = x + 1
        }
    }
    
    // 处理最后一段未被拆分的子数组
    if currentStart < array.count {
        let lastSubArray = Array(array[currentStart...array.count-1])
        result.append(lastSubArray)
    }
    
    return result
}

如果一定要用递归实现

如果你坚持想用递归,需要修改逻辑:找到当前子数组的结束点后终止循环,并且通过返回值收集子数组,避免重复遍历。示例代码如下:

static func splitArrayRecursive(fromArray array: [[String]], startIndex: Int = 1) -> [[[String]]] {
    guard startIndex < array.count else { return [] }
    guard array.allSatisfy({ $0.count > 7 }) else {
        fatalError("数组中存在元素的列数不足8列,无法访问第7列")
    }
    
    var currentEnd = startIndex
    // 找到当前子数组的结束索引(直到下一个元素第7列值不同)
    while currentEnd + 1 < array.count && array[currentEnd][7] == array[currentEnd+1][7] {
        currentEnd += 1
    }
    
    // 切分当前子数组
    let subArray = Array(array[startIndex...currentEnd])
    // 递归处理剩余部分并合并结果
    let remainingSubArrays = splitArrayRecursive(fromArray: array, startIndex: currentEnd + 1)
    
    return [subArray] + remainingSubArrays
}

这个递归版本的逻辑是:每次只处理当前未拆分的一段,找到结束点后就停止遍历,递归处理剩余元素,这样不会出现重复执行的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:46:48