JavaScript实现对象数组混合逻辑过滤:同键OR,异键AND
实现动态多键的AND+OR过滤逻辑
需求回顾
- 对对象数组
data进行过滤,过滤规则由filter对象定义(键对应值为数组) - 同一键的数组元素间采用OR逻辑:对象该键的值只要在数组内,即满足该键的过滤条件
- 不同键之间采用AND逻辑:必须满足所有
filter中定义的键的条件 filter的键数量不固定(2~30个),不能硬编码指定键
错误代码分析
第一段代码问题:
使用Object.keys(currDataRow).some(...),some逻辑是只要有一个键满足条件就返回true,导致全局变成OR逻辑,完全不符合异键AND的要求。第二段代码问题:
错误地将每个过滤键的数组长度累加至countFilter,然后用result == countFilter判断,这要求对象的键值匹配过滤数组的所有元素(同键AND),和需求的同键OR逻辑相反。
正确实现代码
function filterData(data: any[], filter: Record<string, any[]>) { const filterKeys = Object.keys(filter); if (filterKeys.length === 0) return [...data]; return data.filter(obj => { // 所有过滤键必须同时满足(AND逻辑) return filterKeys.every(key => { // 对象存在该键,且值在过滤数组中(OR逻辑) return obj.hasOwnProperty(key) && filter[key].includes(obj[key]); }); }); }
测试验证
使用你提供的示例数据:
const data = [ {a:'1',b:'2'}, {a:'3',b:'4'}, {a:'5',b:'6'} ]; // 测试filter1 const filter1 = {a:['1','3']}; console.log(filterData(data, filter1)); // 输出:[{a:'1',b:'2'}, {a:'3',b:'4'}] // 测试filter2 const filter2 = {a:['1','3'],b:['2']}; console.log(filterData(data, filter2)); // 输出:[{a:'1',b:'2'}]
代码逻辑说明
filterKeys = Object.keys(filter):获取所有需要过滤的键,只处理filter中定义的条件,避免遍历data对象的多余键filterKeys.every(...):通过every确保所有过滤键的条件都满足,实现异键之间的AND逻辑filter[key].includes(obj[key]):检查对象的键值是否存在于过滤数组中,实现同键内的OR逻辑obj.hasOwnProperty(key):避免对象不存在该键时,obj[key]为undefined导致的错误判断
内容的提问来源于stack exchange,提问作者Pablo Souza
相关产品推荐
相关产品推荐

