如何用JavaScript实现忽略末尾数字的字符串高效过滤
性能优化方案
完全可以通过RegExp.test()或者字符串方法替换match()来获得数倍性能提升,原逻辑的性能瓶颈主要来自两点:
match()会生成并返回匹配结果数组,你只需要判断是否匹配的场景下完全不需要这部分开销- 循环中每次动态拼接正则字符串、创建正则实例,重复计算成本高,数组越大浪费越明显
优化方案1:预编译正则 + test()(性能提升最明显)
首先把需要匹配的基础字段提前转义正则特殊字符、预编译成正则实例,避免循环中重复创建:
// 正则特殊字符转义工具函数,避免基础字段包含./*+等正则元字符时匹配出错 function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } // 提前预编译所有匹配规则,只需要执行一次,不用放到循环里 const matchRules = fieldsForSearch.map(c => new RegExp(`^${escapeRegExp(c)}( \\d*)?$`)); // 循环判断逻辑 for (const columnName of this.columnNames) { const isMatch = matchRules.some(rule => rule.test(columnName)); if (isMatch) { // do something... } }
这个写法的正则直接覆盖了「完全等于基础字段」和「基础字段+空格+数字结尾」两种场景,不需要分开写判断,test()只返回布尔值,比match()快3~10倍不等。
优化方案2:纯字符串方法(无正则开销,性能最优)
如果你完全不想用正则,可以用startsWith加后缀校验实现,性能比正则方案还要高:
// 可提前把所有基础字段的前缀缓存好,避免循环中重复拼接 const prefixMap = new Map(fieldsForSearch.map(c => [c, c + ' '])); for (const columnName of this.columnNames) { const isMatch = fieldsForSearch.some(c => { // 情况1:完全等于基础字段 if (columnName === c) return true; // 情况2:基础字段+空格开头,后续字符全是数字 const prefix = prefixMap.get(c); if (columnName.startsWith(prefix)) { const suffix = columnName.slice(prefix.length); return /^\d*$/.test(suffix); } return false; }); if (isMatch) { // do something... } }
效果验证
以上两种方案对示例输入的匹配结果完全符合预期:
输入:['Color', 'Color 1', 'Color 2', 'Color 3', 'Age Range', 'Age Range Minimum', 'Age Range Maximum']
匹配到的结果:['Color', 'Color 1', 'Color 2', 'Color 3']
内容的提问来源于stack exchange,提问作者Fadi
相关产品推荐
相关产品推荐

