纯JS自动补全搜索过滤逻辑修改:优先显示匹配邮政点位
自动补全过滤逻辑优化与实现方案
需求说明
我们拥有数据列表与查询字符串,需修改自动补全(Autocomplete)过滤逻辑:优先展示邮政点位(Post spot),再展示街道等其他字符串,排序需遵循以下规则:
- 若查询为数字,优先筛选左侧带有“№”的项,按数字与“№”的距离由近到远排序,置于结果顶部;
- 无论查询为数字或字符串,其余匹配项按子串位置靠近字符串开头的顺序排序。
示例数据与预期结果
// 外部传入的通常按名称排序的数据 var data = [ '45 Some street, bla bla', 'Again 45 street some', 'More some street xyz', 'Guess what? Some street', 'Post spot №345', 'Post spot №45', 'Post spot №66745' ]; // 用户输入的查询值 var query = '45'; /* 预期排序结果: 1. Post spot №45 // 45与№的距离最近 2. Post spot №345 // 45与№的距离次之 3. Post spot №66745 // 45与№的距离最远 4. 45 Some street, bla bla // 非邮政点位中,45最靠近字符串开头 5. Again 45 street some // 非邮政点位中,45位置次之 */
简洁实现方案
以下是纯JS实现的过滤与排序逻辑,核心分为匹配筛选和优先级排序两步:
function filterAndSortAutocomplete(data, query) { const isNumericQuery = !isNaN(Number(query)); const queryLower = query.toLowerCase(); // 第一步:筛选出所有包含查询子串的项 const matchedItems = data.filter(item => item.toLowerCase().includes(queryLower) ); // 第二步:按规则排序 return matchedItems.sort((a, b) => { // 处理邮政点位带№的优先级(仅当查询为数字时) if (isNumericQuery) { const getDistanceToNo = (str) => { const noIndex = str.indexOf('№'); if (noIndex === -1) return Infinity; // 没有№的项设为无穷大 const queryIndex = str.indexOf(query); return queryIndex - noIndex; // 计算与№的距离,值越小越近 }; const distA = getDistanceToNo(a); const distB = getDistanceToNo(b); // 优先排序距离小的项;若一个有№一个没有,有№的排前面 if (distA !== distB) { return distA - distB; } } // 其余情况:按子串位置靠近开头排序 const posA = a.toLowerCase().indexOf(queryLower); const posB = b.toLowerCase().indexOf(queryLower); return posA - posB; }); } // 调用示例 const result = filterAndSortAutocomplete(data, query); console.log(result);
纯JS自动补全组件推荐
推荐以下内置搜索钩子、支持自定义过滤排序逻辑的纯JS组件:
- Awesomplete:轻量级无依赖组件,体积小,可通过
filter和sort配置项直接注入自定义逻辑,快速集成需求 - AutoComplete.js:功能灵活的纯JS组件,提供
search和sort钩子,支持自定义匹配规则和排序策略 - vanilla-autocomplete:极简纯JS实现,支持自定义数据源处理函数,适合需要高度定制的场景
内容的提问来源于stack exchange,提问作者sl1p
相关产品推荐
相关产品推荐

