JavaScript代码问题:如何筛选包含'bib'所有字符的列表项
修正JavaScript字符筛选逻辑问题
问题描述
需要从列表['rabbit', 'bibe', 'bundle']中筛选出包含字符串'bib'所有字符的元素,预期输出为rabbit和bibe,但原代码错误地输出了所有列表项(bundle因包含字符b被误判符合条件)。
原代码错误分析
let str = 'bib' let list = ['rabbit', 'bibe', 'bundle'] for (let i = 0; i < list.length; i++) { for (let j = 0; j < list[i].length; j++) { let foundIndex = str.indexOf(list[i][j]) > -1 if (foundIndex === -1) { list.splice(foundIndex, 1) } else if (foundIndex) { console.log(list[i]) } } }
原代码存在多处逻辑错误:
- 变量类型混淆:
foundIndex被赋值为布尔值(str.indexOf(...) > -1),后续却和数值-1比较,条件永远不成立 - 判断逻辑颠倒:代码逻辑是「列表项的字符在目标字符串中就输出」,而非「目标字符串的所有字符都在列表项中」
- 数组修改导致遍历异常:直接用
splice修改原数组,会打乱循环索引,导致遍历逻辑混乱 - 匹配条件过松:只要列表项有一个字符匹配就输出,误判了仅包含部分字符的
bundle
修正方案
方案1:基于字符集合的筛选(不考虑字符出现次数)
适合需求为「包含目标字符串所有不同字符」的场景:
const target = 'bib'; // 提取目标字符串的唯一字符集合 const requiredChars = new Set(target); const list = ['rabbit', 'bibe', 'bundle']; // 筛选出包含所有必需字符的元素 const filteredList = list.filter(item => { const itemCharSet = new Set(item); return [...requiredChars].every(char => itemCharSet.has(char)); }); console.log(filteredList); // 输出: ['rabbit', 'bibe']
方案2:基于字符出现次数的筛选(严格匹配字符数量需求)
适合需求为「包含目标字符串所有字符,且每个字符的出现次数不低于目标」的场景(比如'bib'需要至少2个b和1个i):
const target = 'bib'; const list = ['rabbit', 'bibe', 'bundle']; // 统计字符串中各字符的出现次数 const countChars = str => { return str.split('').reduce((countMap, char) => { countMap[char] = (countMap[char] || 0) + 1; return countMap; }, {}); }; const targetCharCounts = countChars(target); const filteredList = list.filter(item => { const itemCharCounts = countChars(item); // 验证每个目标字符的出现次数都满足要求 return Object.entries(targetCharCounts).every(([char, requiredCount]) => { return (itemCharCounts[char] || 0) >= requiredCount; }); }); console.log(filteredList); // 输出: ['rabbit', 'bibe']
内容的提问来源于stack exchange,提问作者Scaplog
相关产品推荐
相关产品推荐

