如何基于多个输入词过滤JavaScript搜索结果?
问题
我需要实现基于输入内容过滤搜索结果,目前只能匹配输入内容作为首个单词前缀的情况,想改成支持匹配输入内容作为任意单词的前缀。比如搜索“funny stories”时,只要书名里有单词以“funny”或“stories”开头(比如书名是“stories”),都要返回结果,而现在只有书名以“funny”开头才会被匹配到。
现有代码:
const filteredSuggestions = suggestions .filter(({name}) => { const match = name.substr(0, searchInput.length); return match && match.toLowerCase() === searchInput.toLowerCase(); });
我尝试了下面的代码,但无法正常工作:
const filteredSuggestions = suggestions .filter(({name}) => { const nameArr = name.split(" "); nameArr.map(name => { const match = name.substr(0, searchInput.length); return match && match.toLowerCase() === searchInput.toLowerCase(); }) });
解决方案
你的代码有两个核心问题:
- 用了
map而非some:map只是遍历数组生成新数组,不会帮你判断是否存在符合条件的元素;而some会在数组里有任意一个元素满足条件时返回true,刚好符合你的需求——只要书名里有任意一个单词前缀匹配搜索词,就保留该结果。 filter回调没有返回值:你当前的filter里没有返回判断结果,默认返回undefined(等价于false),所以过滤后没有结果。
修正后的代码:
const filteredSuggestions = suggestions .filter(({ name }) => { // 把书名拆成单词数组并统一转小写 const nameWords = name.toLowerCase().split(" "); // 搜索词也转小写,避免大小写不匹配 const lowerSearch = searchInput.toLowerCase(); // 检查是否有任意一个单词以搜索词为前缀 return nameWords.some(word => word.startsWith(lowerSearch)); });
拓展:支持多搜索词分别匹配
如果需要实现“搜索多个词时,每个词都要在书名里找到对应的前缀匹配”(比如搜“funny stories”,要求书名同时有以“funny”和“stories”开头的单词),可以把搜索词拆分成数组,用every配合some实现:
const filteredSuggestions = suggestions .filter(({ name }) => { const nameWords = name.toLowerCase().split(" "); // 拆分搜索词并过滤空字符串(避免输入多个空格的情况) const searchWords = searchInput.toLowerCase().split(" ").filter(word => word); // 每个搜索词都要在书名的单词中找到前缀匹配项 return searchWords.every(searchWord => nameWords.some(word => word.startsWith(searchWord)) ); });
内容的提问来源于stack exchange,提问作者learningcoding
相关产品推荐
相关产品推荐

