递归检测重复label函数失效:无法识别同层级重复值
问题:异步递归函数无法检测同层级重复label值
我有一个嵌套JSON结构,由QuestionModel和ResponseModel两个类型构成,两者都包含label属性。我编写了异步递归函数duplicatedLabel,用于检查指定层级的QuestionModel[]或ResponseModel[]数组中是否存在重复的label值,但该函数无法识别同层级的重复label——比如以下示例中同一responses数组内的两个label="yes"对象,函数本应返回true,却始终返回false。
类型定义与原函数代码
type ResponseModel = { label: string; questions?: QuestionModel[]; }; export type QuestionModel = { label: string; responses?: ResponseModel[]; }; const duplicatedLabel = async (data: QuestionModel[] | ResponseModel[]) => { const labelSet = new Set<string>(); for (let obj of data) { if (labelSet.has(obj.label)) { return true; } else { labelSet.add(obj.label); } if ("questions" in obj) return await duplicatedLabel(obj.questions!); if ("responses" in obj) return await duplicatedLabel(obj.responses!); } return false; };
问题示例JSON
[ { "label": "your destination?", "responses": [ { "label": "USA", "questions": [ { "label": "do you have a visa?", "responses": [ { "label": "yes", "questions": [ { "label":"Are you sure" } ] }, { "label": "yes", "questions": [ { "label":"It's your last decision?" } ] } ] } ] }, { "label": "Canada", "questions": [ { "label": "do you have a work licence?", "responses": [ { "label": "yes" }, { "label": "no" } ] } ] } ] } ]
错误原因分析
原函数的核心问题在于循环提前终止:遍历数组时,只要遇到带有questions或responses的对象,就直接return递归调用的结果。这会导致当前层级后续的对象完全没被遍历,自然无法检测到同层级的重复label。比如示例中第一个label="yes"的对象带有questions,函数直接进入递归,递归返回false后整个函数就结束了,第二个label="yes"的对象根本没被检查。
修正后的函数代码
要解决这个问题,需要修改递归调用的逻辑:先判断递归结果,如果子层级存在重复则返回true,否则继续遍历当前层级的所有对象,不能直接终止循环。
const duplicatedLabel = async (data: QuestionModel[] | ResponseModel[]) => { const labelSet = new Set<string>(); for (let obj of data) { // 检查当前层级是否有重复label if (labelSet.has(obj.label)) { return true; } labelSet.add(obj.label); // 递归检查子层级,若子层级有重复则返回true,否则继续循环 if ("questions" in obj && obj.questions) { const hasDuplicateInQuestions = await duplicatedLabel(obj.questions); if (hasDuplicateInQuestions) { return true; } } if ("responses" in obj && obj.responses) { const hasDuplicateInResponses = await duplicatedLabel(obj.responses); if (hasDuplicateInResponses) { return true; } } } return false; };
验证说明
用示例JSON测试修正后的函数:遍历到第二个label="yes"的对象时,labelSet已经存在该值,会直接返回true,符合预期。同时子层级的重复label也能正常检测。
内容的提问来源于stack exchange,提问作者DONGMO BERNARD GERAUD
相关产品推荐
相关产品推荐

