You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Vanilla JavaScript的可筛选列表:如何实现任意子串匹配?

实现任意顺序子串匹配的姓名筛选列表修改方案

嘿,这个需求我太熟了!你现在的筛选逻辑应该是用了includes()这类方法,只能匹配连续的子串,所以输入dm找不到Adam。要实现输入任意字符(只要按顺序出现在姓名里)就能匹配,核心是改成按顺序的非连续子串匹配,我给你一步步拆解怎么改:

先看原逻辑的问题

假设你原来的筛选代码大概是这样的:

// 原连续子串匹配逻辑
function filterNames(inputValue, names) {
  return names.filter(name => 
    name.toLowerCase().includes(inputValue.toLowerCase())
  );
}

includes()要求输入的字符串是姓名里的一段连续内容,所以dm这种不连续的组合就匹配不上。

修改后的核心逻辑

我们需要写一个辅助函数,检查输入的每个字符是否按顺序出现在姓名中(不要求连续)。直接上可复用的代码:

// 辅助函数:验证输入字符是否按顺序存在于目标姓名中
function matchesOrderedSubsequence(input, target) {
  const inputLower = input.trim().toLowerCase();
  const targetLower = target.toLowerCase();
  let inputPointer = 0;

  // 如果输入为空,直接返回匹配
  if (!inputLower) return true;

  // 遍历目标姓名的每个字符
  for (const char of targetLower) {
    // 匹配到输入的当前字符,就移动输入指针
    if (char === inputLower[inputPointer]) {
      inputPointer++;
      // 输入的所有字符都匹配完成,直接返回true
      if (inputPointer === inputLower.length) {
        return true;
      }
    }
  }

  // 遍历完姓名还没匹配完所有输入字符,返回false
  return inputPointer === inputLower.length;
}

// 修改后的筛选函数
function filterNames(inputValue, names) {
  return names.filter(name => matchesOrderedSubsequence(inputValue, name));
}

逻辑验证示例

比如输入dm匹配Adam的过程:

  1. 输入转成小写是dm,姓名转成小写是adam
  2. 遍历adam的第一个字符a,不匹配d,跳过
  3. 第二个字符d,匹配输入的第一个字符,输入指针移到1(对应m)
  4. 第三个字符a,不匹配m,跳过
  5. 第四个字符m,匹配输入的第二个字符,输入指针移到2,等于输入长度,返回true,所以Adam会被筛选出来

同样,输入da的时候,会匹配到adam里的d和后面的a,也能成功匹配。

结合DOM使用的完整示例

如果要和你的输入框绑定,完整可运行的代码大概是这样的:

<input type="text" id="nameFilter" placeholder="输入任意字符筛选...">
<ul id="nameList"></ul>

<script>
const names = ['Adam', 'Bob', 'David', 'Amanda', 'Emma'];
const filterInput = document.getElementById('nameFilter');
const nameList = document.getElementById('nameList');

// 辅助匹配函数
function matchesOrderedSubsequence(input, target) {
  const inputLower = input.trim().toLowerCase();
  const targetLower = target.toLowerCase();
  let inputPointer = 0;

  if (!inputLower) return true;

  for (const char of targetLower) {
    if (char === inputLower[inputPointer]) {
      inputPointer++;
      if (inputPointer === inputLower.length) {
        return true;
      }
    }
  }

  return inputPointer === inputLower.length;
}

// 筛选函数
function filterNames(inputValue, names) {
  return names.filter(name => matchesOrderedSubsequence(inputValue, name));
}

// 渲染列表
function renderFilteredList(filteredNames) {
  nameList.innerHTML = filteredNames.map(name => `<li>${name}</li>`).join('');
}

// 初始渲染
renderFilteredList(names);

// 监听输入变化
filterInput.addEventListener('input', (e) => {
  const filteredNames = filterNames(e.target.value, names);
  renderFilteredList(filteredNames);
});
</script>

这样修改后,只要输入的字符是按姓名里的顺序出现的(比如dm、da、am都能匹配Adam),就能筛选出对应的姓名啦!

内容的提问来源于stack exchange,提问作者Magnetic Kode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:05:53