JavaScript中如何最优比较两个数组字符串并统计匹配数量?
解决方案:统计技能匹配数量
首先先把你的示例代码放出来:
var job = ['javascript','nodejs','angularjs','css','html','graphql']; var candidate= ['javascript','node', 'css', 'html', 'postgres', 'sql', 'express', 'python', 'c#'];
从你的例子来看,你需要的是模糊匹配(比如node能匹配nodejs),而不是严格的字符串相等,下面分几种场景给你实用方案:
1. 简单直接版(适合小数据量)
这种方法新手也能快速看懂,适合数组长度不大的日常场景:
// 筛选出所有符合匹配条件的候选人技能,再取长度 const matchingSkills = candidate.filter(skill => { // 检查职位技能里是否有包含当前候选人技能的项 return job.some(jobSkill => jobSkill.includes(skill)); }); const matchCount = matchingSkills.length; console.log(matchCount); // 输出4,和你的示例一致
说明:
filter遍历候选人的每个技能,some则检查职位技能里有没有满足「包含该技能」的项- 优点:代码简洁易懂,不需要额外依赖
- 缺点:时间复杂度是O(n*m),如果两个数组都很大(比如上千条数据),性能会有点慢
2. 匹配规则调整
如果你想要更精确的匹配逻辑,可以直接修改判断条件:
- 前缀匹配:只允许候选人技能作为职位技能的前缀(比如
node匹配nodejs,但js不会匹配javascript),把includes换成startsWith即可:const matchingSkills = candidate.filter(skill => job.some(jobSkill => jobSkill.startsWith(skill)) ); - 严格精确匹配:只有完全相同的字符串才算匹配(比如
node不会匹配nodejs),直接用includes检查:const matchingSkills = candidate.filter(skill => job.includes(skill)); // 这种情况示例的匹配数是3(javascript、css、html)
3. 高性能版(适合大数据量)
如果你的技能数组非常大(比如有成百上千条技能),可以用**前缀树(Trie)**来优化性能,把匹配的时间复杂度降到O(k)(k是技能字符串的长度):
// 先实现一个简单的前缀树 class TrieNode { constructor() { this.children = {}; this.isEnd = false; } } class Trie { constructor() { this.root = new TrieNode(); } // 插入职位技能到前缀树 insert(word) { let node = this.root; for (const char of word) { if (!node.children[char]) { node.children[char] = new TrieNode(); } node = node.children[char]; } node.isEnd = true; } // 检查是否有职位技能以当前候选人技能为前缀 startsWith(prefix) { let node = this.root; for (const char of prefix) { if (!node.children[char]) { return false; } node = node.children[char]; } return true; } } // 使用前缀树统计匹配数 const skillTrie = new Trie(); job.forEach(skill => skillTrie.insert(skill)); const matchCount = candidate.filter(skill => skillTrie.startsWith(skill)).length; console.log(matchCount); // 输出4
说明:
- 前缀树适合大量字符串的前缀匹配场景,插入和查询的效率都很高
- 如果需要处理大小写不敏感的情况,插入和查询的时候统一转成小写即可
额外注意事项
- 大小写问题:如果需要忽略大小写匹配(比如
JavaScript和javascript算匹配),可以在检查时统一转成小写:job.some(jobSkill => jobSkill.toLowerCase().includes(skill.toLowerCase())) - 重复技能:如果候选人数组里有重复技能(比如两个
javascript),可以先去重再统计:const uniqueCandidateSkills = [...new Set(candidate)]; const matchCount = uniqueCandidateSkills.filter(...).length;
内容的提问来源于stack exchange,提问作者hackrack
相关产品推荐
相关产品推荐

