如何基于多个值实现JavaScript数组的高效过滤?
你当前的写法会对数组执行多次遍历,每次filter都要完整遍历一次数组,数据量大时会产生不必要的性能损耗,同时过滤条件分散在多处,后续维护修改也不方便。推荐以下两种更优的实践:
方案1:合并条件单次过滤(适配固定过滤场景)
把所有需要排除的地区名存在Set集合中,单次过滤就完成所有判断,仅遍历数组1次,性能最优,代码也更简洁易维护。
import axios from 'axios' export const stats_API = async (setWorldStats, setcasesAcrossWorld) => { try { const url = `https://covid-193.p.rapidapi.com/statistics` const headers = { 'x-rapidapi-host': 'covid-193.p.rapidapi.com', 'x-rapidapi-key': '******************', } const { data } = await axios.get(url, { headers }) let casesAcrossWorld_Arr = data.response.filter((val) => { return val.country === 'All' }) setcasesAcrossWorld(casesAcrossWorld_Arr[0]) // 提前定义所有需要排除的地区,Set的has查询性能远高于Array.includes const excludeRegions = new Set(['All', 'Asia', 'Europe', 'Africa', 'North-America', 'South-America', 'Oceania']) // 单次过滤完成所有判断 const worldStats_Arr = data.response.filter(val => !excludeRegions.has(val.country)) setWorldStats(worldStats_Arr) } catch (error) { console.log(error) } }
如果后续需要新增/删除排除的地区,只需要修改excludeRegions集合内的元素即可,不需要调整过滤逻辑。
方案2:可配置过滤规则集合(适配动态多场景过滤需求)
如果你的过滤条件会根据不同业务场景动态切换、新增,可以把所有过滤规则封装成独立的数组,后续加规则不需要修改过滤执行逻辑,仅需新增规则项即可。
// 过滤规则数组,每一项都是判断函数,返回true代表保留当前项 const filterRules = [ // 规则1:排除All和亚洲 val => !['All', 'Asia'].includes(val.country), // 规则2:排除欧洲和非洲 val => !['Europe', 'Africa'].includes(val.country), // 规则3:排除南北美洲 val => !['North-America', 'South-America'].includes(val.country), // 规则4:排除大洋洲 val => !['Oceania'].includes(val.country), // 后续新增规则直接在这里加即可,比如新增过滤累计病例小于1000的地区: // val => val.cases.total >= 1000 ] export const stats_API = async (setWorldStats, setcasesAcrossWorld) => { try { const url = `https://covid-193.p.rapidapi.com/statistics` const headers = { 'x-rapidapi-host': 'covid-193.p.rapidapi.com', 'x-rapidapi-key': '******************', } const { data } = await axios.get(url, { headers }) let casesAcrossWorld_Arr = data.response.filter((val) => { return val.country === 'All' }) setcasesAcrossWorld(casesAcrossWorld_Arr[0]) // 单次遍历,所有规则校验通过才保留项 const worldStats_Arr = data.response.filter(val => { return filterRules.every(rule => rule(val)) }) setWorldStats(worldStats_Arr) } catch (error) { console.log(error) } }
这种方案适配性更强,比如你要做前端自定义筛选面板,用户勾选要排除的地区时,直接动态生成filterRules数组即可,不需要修改核心逻辑。
内容的提问来源于stack exchange,提问作者Akhil Rana
相关产品推荐
相关产品推荐

