
本文介绍如何在 javascript 中对对象数组先按关键词模糊过滤,再按关键词在字符串中首次出现的位置升序排序,从而实现“前缀匹配优先”的搜索结果排序效果。
本文介绍如何在 javascript 中对对象数组先按关键词模糊过滤,再按关键词在字符串中首次出现的位置升序排序,从而实现“前缀匹配优先”的搜索结果排序效果。
在实际开发中,仅使用 filter() 进行模糊匹配(如 includes())虽能筛选出含关键词的所有项,但无法体现匹配质量差异——例如用户输入 "po" 时,"poland" 和 "portugal" 是理想的前缀匹配项,而 "singpore"("po" 出现在第6位)和 "French Polynesia"("po" 出现在第8位)匹配位置靠后,理应排在后面。为提升用户体验,需在过滤后引入排序逻辑,依据关键词在 name 字段中首次出现的索引位置(indexOf) 进行升序排列。
具体实现分为两步:
-
过滤:保留
name.toLowerCase().includes(searchText)为true的对象; -
排序:使用
sort()比较每个对象中searchText在name.toLowerCase()中的起始索引,索引越小越靠前。
以下是完整可运行示例:
let array = [
{ name: "singpore" },
{ name: "French Polynesia" },
{ name: "poland" },
{ name: "portugal" }
];
let searchText = "po";
let result = array
.filter(item => item.name.toLowerCase().includes(searchText))
.sort((a, b) => {
const idxA = a.name.toLowerCase().indexOf(searchText);
const idxB = b.name.toLowerCase().indexOf(searchText);
return idxA - idxB;
});
console.log(result);
// 输出:
// [
// { name: "poland" },
// { name: "portugal" },
// { name: "singpore" },
// { name: "French Polynesia" }
// ]
⚠️ 注意事项:
-
indexOf()返回-1表示未找到,但因已通过filter()确保所有项均包含searchText,故无需额外处理负值; - 若需支持大小写敏感搜索,可移除
.toLowerCase()调用,但需确保searchText大小写与数据一致; - 对于更复杂的搜索场景(如多字段匹配、拼音检索、权重打分),建议结合
localeCompare()或引入专用库(如 Fuse.js); - 性能方面,该方案适用于中等规模数据(
通过 filter + sort 的组合策略,既能保持代码简洁性,又能精准控制搜索结果的相关性排序,是前端搜索功能中的经典实践。










