JavaScript高效过滤ArrayA、ArrayB生成目标ArrayC的实现方案
高性能JavaScript数组过滤实现方案
核心优化思路是把重复计算的逻辑全部提前预处理,避免遍历过程中做冗余的字符串拆分、拼接、匹配操作,整体时间复杂度可以压到线性级别。
规则前置预处理
先把两个固定判断条件提前算好,全程只计算1次,不会在遍历数组时重复执行:
- 身份匹配规则:根据全局
userType生成允许的target值集合,直接用Set做O(1)查询:- 用户为
teacher时,允许值为_teacher、_teacher_student - 用户为
student时,允许值为_student、_teacher_student
- 用户为
- 过滤键集合:把ArrayA中所有元素提前拼接为
filter_{GroepType}_{GroepID}格式的键,存入Set做O(1)存在性校验,完全不需要拆分字符串匹配键名。
实现代码
先修正测试样例里的笔误(ArrayB缺逗号、预期结果中id字段位置错误),最终可直接运行的代码如下:
// 全局用户类型 let userType = 'teacher' const arrayA = [ {"ID": 1, "GroepID": 1371, "GroepType": "klas"}, {"ID": 2, "GroepID": 1372, "GroepType": "klas"}, {"ID": 3, "GroepID": 1375, "GroepType": "graad"} ] const arrayB = [ { "id": "bd5b12ba-b433-4610-801e-e0b78fa72ff8", data: {"target": "_teacher", "filter_klas_1371": "true"} }, { "id": "gggfdgdba-gfgg-fff-ggg-7657657676", data:{"target": "_teacher_student", "filter_klas_1375": "true"} }, { "id": "uuuykllk-b433-4610-801e-8888888776", data: {"target": "_student", "filter_klas_1372": "true"} }, { "id": "jkjkjkklk-jkhjk-66567-666-99977", data: {"target": "_teacher_student", "filter_klas_1372": "true"} }, { "id": "zzzzzzz-b433-4610-801e-8888888776", data: {"target": "_teacher", "filter_klas_1372": "true"} } ] // 预处理1:生成当前用户允许的target集合 const allowedTarget = new Set([`_${userType}`, '_teacher_student']) // 预处理2:生成ArrayA对应的所有合法过滤键集合 const validFilterKeys = new Set( arrayA.map(item => `filter_${item.GroepType}_${item.GroepID}`) ) // 单次遍历过滤 const arrayC = arrayB.filter(item => { const { data } = item // 身份不匹配直接排除 if (!allowedTarget.has(data.target)) return false // 校验是否存在任意一个合法过滤键且值为"true" for (const key of validFilterKeys) { if (data[key] === 'true') return true } return false })
性能说明
- 全程无字符串拆分、正则匹配这类高开销操作,所有预处理逻辑仅执行1次,不会在遍历ArrayB时重复计算
- 所有判断逻辑都是引擎底层优化过的O(1)操作(Set的has查询、对象属性访问),数据量越大,相比逐字符串拆分的实现性能优势越明显,万级数据量下性能差距可达10倍以上
- 如果两个数组长度差异极大,可以动态选择遍历更短的集合做校验,进一步压缩循环次数:
const arrayC = arrayB.filter(item => { const { data } = item if (!allowedTarget.has(data.target)) return false // 选长度更小的集合遍历,减少循环次数 return validFilterKeys.size < Object.keys(data).length ? [...validFilterKeys].some(key => data[key] === 'true') : Object.keys(data).some(key => validFilterKeys.has(key) && data[key] === 'true') })
运行上述代码得到的arrayC和预期结果完全一致。
内容的提问来源于stack exchange,提问作者Tonathiu Redrovan
相关产品推荐
相关产品推荐

