JavaScript Map对象过滤异常排查:搜索匹配未返回预期结果
Map过滤函数问题排查
问题背景
我有一个结构如下的Map对象input,需要根据搜索输入字符串filterFailureInput过滤条目:检查每个条目的testErrorSummary、appErrorSummary属性,以及invocations数组中每个元素的radar属性,只要任意一个属性匹配搜索字符串,就保留该Map条目。
例如当filterFailureInput = "50"时,预期仅返回key为0的条目(因为该条目的invocations中有一个radar值为"3450",包含"50"),但我实现的searchException函数未得到预期结果,需要排查代码问题。
输入数据
const input = new Map([ [ 0, { testErrorSummary: "ServiceC\nV4/\n\tcom.dmv.smp", appErrorSummary: '{"handler":null,"sourcetype":null}', invocations: [ { radar: "", testCaseMilestone: "1G05" }, { radar: "3450", testCaseMilestone: "1G15" }, ], }, ], [ 1, { testErrorSummary: 'java: \nEx:\n <"()">\n <" "code": "403"">', appErrorSummary: '{"handler":null,"sourcetype":null}', invocations: [ { radar: "1532", testCaseMilestone: "1G12" }, { radar: "1954", testCaseMilestone: "1G24" }, ], }, ], [ 2, { testErrorSummary: "com.dmv: Timeout while waiting.", appErrorSummaryKeyword: 'Cannot invoke "com.dmv.getEcid()"', hasRadarHistory: false, invocations: [ { radar: "3444", testCaseMilestone: "1G45" }, { radar: "", testCaseMilestone: "1G90" }, ], }, ], ]);
预期输出(当filterFailureInput = "50"时)
new Map([ [ 0, { testErrorSummary: "ServiceC\nV4/\n\tcom.dmv.smp", appErrorSummary: '{"handler":null,"sourcetype":null}', invocations: [ { radar: "", testCaseMilestone: "1G05" }, { radar: "3450", testCaseMilestone: "1G15" }, ], }, ], ]);
现有问题代码
const searchException = () => { return new Map( Array.from(input).filter(([key, value]) => { const matchInvocations = value.invocations.some( (invocation) => { (invocation?.radar && invocation?.radar.includes(filterFailureInput)) || (value?.testErrorSummary?.toLowerCase() .includes(filterFailureInput.toLowerCase())) || (value?.appErrorSummaryKeyword?.toLowerCase() .includes(filterFailureInput.toLowerCase())) }); return matchInvocations; }) ); }; const expectedOutput = searchException();
问题分析
- 逻辑范围错误:把
testErrorSummary和appErrorSummaryKeyword的匹配判断放在了invocations.some()的回调函数内,导致这两个字段的检查会被每个invocation重复执行,且逻辑上变成了「每个invocation都要满足radar匹配,或者整个条目的testErrorSummary匹配,或者appErrorSummaryKeyword匹配」——这完全不符合需求,需求应该是「条目满足任意一个条件:radar有匹配、testErrorSummary匹配、appErrorSummary匹配、appErrorSummaryKeyword匹配」。 - 遗漏
appErrorSummary字段检查:需求明确要求检查appErrorSummary,但现有代码完全没处理这个字段。 - 大小写处理不一致:
radar的匹配没有做大小写转换,而其他字段做了,会导致大小写敏感的匹配问题。 - 语法可读性问题:
some回调内的逻辑没有用完整括号包裹,虽然语法合法,但容易导致逻辑混淆。
修复后的代码
const searchException = () => { // 统一处理搜索关键词的大小写,避免大小写敏感问题 const lowerCaseFilter = filterFailureInput.toLowerCase(); return new Map( Array.from(input).filter(([key, value]) => { // 检查testErrorSummary是否匹配 const matchesTestError = value?.testErrorSummary?.toLowerCase().includes(lowerCaseFilter); // 检查appErrorSummary是否匹配 const matchesAppError = value?.appErrorSummary?.toLowerCase().includes(lowerCaseFilter); // 检查appErrorSummaryKeyword是否匹配 const matchesAppErrorKeyword = value?.appErrorSummaryKeyword?.toLowerCase().includes(lowerCaseFilter); // 检查invocations中是否有radar匹配 const matchesRadar = value.invocations.some(invocation => invocation?.radar?.toLowerCase().includes(lowerCaseFilter) ); // 任意一个条件满足则保留该条目 return matchesTestError || matchesAppError || matchesAppErrorKeyword || matchesRadar; }) ); }; const expectedOutput = searchException();
修复说明
- 统一将搜索关键词和待匹配字段转成小写,实现大小写不敏感的匹配。
- 把各个匹配条件拆分单独判断,逻辑更清晰易维护。
- 补充了
appErrorSummary字段的检查,符合需求。 - 将radar的判断放在
invocations.some()内,而其他字段的判断放在外部,确保逻辑是「条目满足任意一个条件即保留」。
内容的提问来源于stack exchange,提问作者Aren Trot
相关产品推荐
相关产品推荐

