TS/JS实现对象数组多列过滤:同列OR、异列AND逻辑
多列复选框列表过滤实现方案
原有代码问题
原实现用Array.some()遍历所有筛选条件,逻辑等价于「只要命中任意一个筛选项就保留条目」,所有筛选项之间是全OR关系,无法满足不同列之间的AND要求。
核心规则
- 同一列下的多个选中值:OR逻辑,条目在该列的值匹配任意一个选中值即满足本列要求
- 不同列之间:AND逻辑,条目必须满足所有存在选中值的列的要求,才会被保留
实现步骤
- 先对扁平的选中筛选项按字段名分组,把同一列的选中值归集到同一个数组中,避免过滤每条数据时重复处理筛选条件
- 过滤列表时,对每一条数据校验所有分组后的筛选列:所有列都满足匹配要求才保留该条目
完整代码
// 原始全量列表 const ListAllItems = [{ Value1: "val", Value2: "more value", Value3: "1" },{ Value1: "val1", Value2: "test", Value3: "1" },{ Value1: "val1", Value2: "test", Value3: "2" },{ Value1: "val", Value2: "test", Value3: "3" }]; // 用户勾选的筛选项集合 let newFilterObj = [ { fieldName: "Value3", value: "3" }, { fieldName: "Value3", value: "2" }, { fieldName: "Value1", value: "val1" } ] // 筛选条件按字段分组(仅在筛选项变化时执行1次即可,无需每条数据过滤时重复计算) const groupedFilter = newFilterObj.reduce((res, condition) => { const { fieldName, value } = condition; if (!res[fieldName]) res[fieldName] = []; res[fieldName].push(value); return res; }, {}); // 执行过滤 const newList = ListAllItems.filter(item => { // 所有筛选列必须全部满足要求(跨列AND) return Object.entries(groupedFilter).every(([field, allowedValues]) => { // 当前列匹配任意选中值即通过本列校验(同列OR) return allowedValues.includes(item[field]); }); });
性能说明
针对数千条量级的列表,该实现性能完全足够:分组操作仅在用户修改勾选状态时触发一次,单条数据的校验逻辑为简单的数组包含判断,无冗余计算,不会出现卡顿。
注意:使用时请保证筛选项的
fieldName和列表条目字段名大小写完全一致,否则会出现匹配失效问题。
内容的提问来源于stack exchange,提问作者EirikAanstad
相关产品推荐
相关产品推荐

