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

JavaScript递归函数返回列表全为相同条目的原因排查

递归生成课程组合笛卡尔积时返回列表所有对象重复问题排查

问题根因

你遇到的所有返回条目完全相同的问题,核心原因是JavaScript中对象为引用类型,递归全程没有做对象拷贝,所有分支操作、返回的都是内存中的同一个对象。

具体错误点有两处:

  • 递归传参时直接传递dictSoFar的引用,没有为每个组合分支创建独立的对象副本。for循环中每次修改dictSoFar的属性值,都会同步修改所有递归分支中持有的同一个对象,之前已经存入结果数组的对象值会被后续循环的修改覆盖。
  • 递归基准条件直接返回[dictSoFar],存入结果数组的是同一个对象的引用,不是独立的对象实例。等所有递归循环跑完,这个公共对象里存的是最后一次遍历到的组合值,最终数组里120个指向同一内存地址的引用,打印出来自然全是相同内容。

另外你原代码中用filter过滤当前课程的写法没有必要,每次处理的都是列表首元素,直接用slice(1)截取剩余课程列表即可,性能更高也不会出现引用判断的异常。

修正后代码

function recursiveFunction(listOfCourses, dictSoFar) {
    // 基准条件:课程列表遍历完成,返回当前组合的独立对象副本
    if (!listOfCourses.length) {
        return [{ ...dictSoFar }]
    }

    const arraySoFar = []
    const currentCourse = listOfCourses[0]
    // 直接截取剩余待处理课程,无需filter遍历
    const restCourses = listOfCourses.slice(1)

    for (const combo of currentCourse.possibleCombos) {
        // 每个组合分支创建独立的字典副本,避免跨分支修改污染
        const nextDict = {
            ...dictSoFar,
            [currentCourse.courseCode]: combo
        }
        // 传入独立副本递归处理剩余课程
        const branchResult = recursiveFunction(restCourses, nextDict)
        arraySoFar.push(...branchResult)
    }

    return arraySoFar
}

验证说明

传入你提供的测试数据运行,返回数组长度为5*4*6=120,每个对象都是独立实例,完整覆盖所有课程可选值的笛卡尔积组合,不会出现条目重复的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:51:22