如何编写生成问卷所有可能路径的测试脚本?现有代码异常求方案
问卷全路径生成脚本修复方案
问题描述
需要编写JavaScript脚本生成问卷所有可能的跳转路径,问卷会根据用户回答跳转到对应问题。当前编写的代码无法正常运行,无法得到预期输出,寻求正确实现方案。
问题代码
const questions = [{ id: "1", question: "q1", answer_1: { text: "a1", next_question: "2", }, answer_2: { text: "a2", next_question: "3", }, }, { id: "2", question: "q2", answer_1: { text: "a1/a2", next_question: "", }, }, { id: "3", question: "q3", answer_1: { text: "a1", next_question: "", }, answer_2: { text: "a2", next_question: "4", }, }, { id: "4", question: "q4", answer_1: { text: "a1", next_question: "", }, }, ]; const newObj = {}; const getAllPath = (arr) => { const treeStructure = arr.forEach((item) => { newObj[item.id] = { ...item, children: [ ...Object.keys(item) .filter((k) => k.includes("answer")) .map((k) => ({ ...item[k] })), ], }; }); const newBranches = ({ question, children }) => children.map(({ text, next_question }) => next_question.length === 0 ? { [question]: text } : newBranches(newObj[next_question]).map((obj) => ({ [question]: text, ...obj, })) ); return newBranches(newObj[arr[0].id]); }; let result = { path: { list: getAllPath(questions), }, }; console.log(result);
预期输出
{ paths: { list: [ [{ "q1": "a1" }, { "q2": "a1/a2" } ], [{ "q1": "a2" }, { "q3": "a1" } ], [{ "q1": "a2" }, { "q3": "a2" }, { "q4": "a1" } ], ] } }
问题分析
原代码核心问题在于递归逻辑处理错误:
newBranches返回嵌套数组,未正确扁平化并组装成路径数组- 递归时直接合并对象,而非将每一步的问答对象加入路径数组
修复后的实现方案
采用**深度优先搜索(DFS)**遍历所有可能路径,每一步记录当前问答节点,直到无后续问题时将完整路径存入结果:
const questions = [{ id: "1", question: "q1", answer_1: { text: "a1", next_question: "2" }, answer_2: { text: "a2", next_question: "3" }, }, { id: "2", question: "q2", answer_1: { text: "a1/a2", next_question: "" }, }, { id: "3", question: "q3", answer_1: { text: "a1", next_question: "" }, answer_2: { text: "a2", next_question: "4" }, }, { id: "4", question: "q4", answer_1: { text: "a1", next_question: "" }, }, ]; // 将问题数组转为id映射对象,方便快速查找 const questionMap = questions.reduce((map, q) => { map[q.id] = q; // 提取当前问题的所有答案为统一数组 map[q.id].answers = Object.keys(q) .filter(key => key.startsWith('answer_')) .map(key => q[key]); return map; }, {}); // 深度优先搜索收集所有路径 const getAllPaths = () => { const result = []; // 递归函数:当前问题id,当前路径数组 const dfs = (questionId, currentPath) => { const currentQuestion = questionMap[questionId]; if (!currentQuestion) return; // 遍历当前问题的所有答案 currentQuestion.answers.forEach(answer => { // 将当前问答加入路径 const newPath = [...currentPath, { [currentQuestion.question]: answer.text }]; if (answer.next_question) { // 有后续问题,继续递归 dfs(answer.next_question, newPath); } else { // 无后续问题,将完整路径存入结果 result.push(newPath); } }); }; // 从第一个问题开始遍历 dfs('1', []); return result; }; // 生成最终结果 const finalResult = { paths: { list: getAllPaths() } }; console.log(finalResult);
代码说明
- questionMap构建:将原问题数组转为以id为键的对象,同时提取每个问题的所有答案为统一数组,简化后续遍历
- DFS递归逻辑:
- 每次递归接收当前问题id和已走路径
- 遍历当前问题的所有答案,生成新路径
- 如果答案有后续问题,继续递归;否则将完整路径加入结果数组
- 结果结构:最终输出完全匹配预期格式,每个路径是包含问答对象的数组
内容的提问来源于stack exchange,提问作者userName
相关产品推荐
相关产品推荐

