如何基于URL查询参数为动态返回的数组对象创建自定义多条件过滤逻辑
实现思路
我们可以通过可配置的规则映射表来解耦查询参数和实际业务判断逻辑,后续新增筛选条件只需要在映射表里加规则即可,不用改核心过滤逻辑:
- 先把查询参数里逗号分隔的字符串拆成数组,方便匹配判断
- 定义每个查询参数对应的判断规则,支持多条件匹配
- 遍历数组时,所有查询规则都通过的项才会被保留
完整代码实现
// 原数据 const query = { channels: 'calls,texts', calls: 'voicemail,missed', }; const arr = [ { id: 1, channel: 'SMS', sent: '2021-08-22T03:21:18.41650+0000', sender: { contactType: 'business' }, recipients: [{ contactType: 'corporate' }], direction: 'INBOUND', }, { id: 2, channel: 'VOICE', sent: '2021-08-20T23:15:56.00000+0000', sender: { contactType: 'business' }, recipients: [{ contactType: 'corporate' }], callDetails: { answered: false, voicemail: true }, direction: 'INBOUND', }, { id: 3, channel: 'VOICE', sent: '2021-08-20T23:15:56.00000+0000', sender: { contactType: 'business' }, recipients: [{ contactType: 'corporate' }], callDetails: { answered: true, voicemail: false }, direction: 'INBOUND', }, { id: 4, channel: 'VOICE', sent: '2021-08-20T23:15:56.00000+0000', sender: { contactType: 'business' }, recipients: [{ contactType: 'corporate' }], callDetails: { answered: false, voicemail: false }, direction: 'INBOUND', }, ]; // 1. 预处理查询参数,拆分逗号分隔的取值 const parsedQuery = Object.fromEntries( Object.entries(query).map(([key, value]) => [key, value.split(',')]) ); // 2. 核心:查询参数 -> 业务判断规则的映射配置 const filterConfig = { // channels参数的判断规则 channels: (item, allowedValues) => { // 业务字段值和查询参数的映射 const channelMap = { 'SMS': 'texts', 'VOICE': 'calls' }; const currentChannel = channelMap[item.channel]; // 当前通道在允许列表里即通过校验 return allowedValues.includes(currentChannel); }, // calls参数的判断规则 calls: (item, allowedValues) => { // 非通话类的项直接跳过本规则校验 if (item.channel !== 'VOICE') return true; // 配置calls参数取值对应的判断逻辑 const callRuleMap = { 'voicemail': () => item.callDetails?.voicemail === true, 'missed': () => item.callDetails?.answered === false, 'received': () => item.callDetails?.answered === true }; // 命中任意一个允许的规则即通过校验 return allowedValues.some(ruleKey => callRuleMap[ruleKey]?.()); } }; // 3. 执行筛选 const filteredResult = arr.filter(item => { // 所有查询参数的规则都通过才保留项 return Object.entries(parsedQuery).every(([queryKey, allowedValues]) => { const validator = filterConfig[queryKey]; // 没有配置规则的查询参数直接跳过 return validator ? validator(item, allowedValues) : true; }); }); console.log(filteredResult.map(i => i.id)); // 输出 [1,2,4],完全符合需求
扩展性说明
后续如果新增其他查询参数,比如要加direction=INBOUND的筛选,只需要在filterConfig里加对应的规则即可,不用修改核心过滤逻辑:
const filterConfig = { // ...原有规则保持不变 direction: (item, allowedValues) => allowedValues.includes(item.direction) }
内容的提问来源于stack exchange,提问作者victorjaquez
相关产品推荐
相关产品推荐

