JavaScript 基于条件数组实现分组或逻辑的可扩展多条件筛选
通用多分组筛选实现方案
- 原有硬编码逻辑的问题是把分组关系、组内/组间的逻辑规则写死在分支判断里,新增分组就需要新增分支,维护成本随分组数量线性上升。
- 解决的核心是把「分组关系」从逻辑代码中抽离成可维护的配置项,筛选逻辑完全和具体分组解耦,遵循统一规则:同分组内逻辑或,跨分组逻辑与,无选中条件的分组不参与筛选限制。
步骤1:定义全局分组配置
把所有筛选字段的所属关系抽成配置表,后续新增分组、调整分组关系只需要修改这部分配置,不需要改动核心筛选逻辑:
const FILTER_GROUPS = { // 舒适度分组:同组内逻辑或 comfort: ['AC', 'nonAC'], // 座位类型分组:同组内逻辑或 seatType: ['sleeper', 'seater'], // 后续新增分组直接在此处追加即可,例如: // availableGroup: ['availCatCard'] }
步骤2:实现通用的条件聚合逻辑
把Redux中存储的扁平格式筛选条件(如[{AC:'true'},{nonAC:'true'},{sleeper:'true'}]),按照分组配置聚合到对应分组下,去掉写死的字段判断:
/** * 扁平筛选条件 -> 按分组聚合 * @param {Array} flatCond Redux存储的扁平筛选条件 * @param {Object} groupConfig 全局分组配置表 * @returns {Object} 聚合后的分组条件 */ function aggregateGroupedCond(flatCond, groupConfig) { return Object.entries(groupConfig).reduce((groupedRes, [groupId, fields]) => { // 从所有扁平条件中,筛选出属于当前分组的选中项 groupedRes[groupId] = flatCond.flatMap(condItem => { const [field, matchVal] = Object.entries(condItem)[0] return fields.includes(field) ? [{ field, matchVal }] : [] }) return groupedRes }, {}) }
步骤3:实现通用过滤逻辑
按照统一规则(同组或、跨组与)遍历待筛选数据,不需要针对任何特定分组写分支判断:
/** * 通用多分组过滤 * @param {Array} dataSource 待筛选的原始对象数组 * @param {Array} flatFilterCond 扁平格式的用户选中筛选条件 * @param {Object} groupConfig 全局分组配置表 * @returns {Array} 过滤后的结果数组 */ function universalMultiGroupFilter(dataSource, flatFilterCond, groupConfig) { const groupedConds = aggregateGroupedCond(flatFilterCond, groupConfig) return dataSource.filter(item => { // 跨组逻辑与:所有分组的检查都通过,才保留当前项 return Object.values(groupedConds).every(groupConds => { // 分组无选中条件,直接通过不做限制 if (!groupConds.length) return true // 组内逻辑或:匹配当前分组任意一个选中条件,就算通过该分组检查 return groupConds.some(cond => item[cond.field] === cond.matchVal) }) }) }
效果验证
用提供的示例数据测试:
// 原始待筛选数组 const sourceArray = [ { "AC": "false", "nonAC": "true", "sleeper":"true", "availCatCard": "false" }, { "AC": "true", "nonAC": "false", "sleeper":"false", "availCatCard": "false" }, { "AC": "true", "nonAC": "true", "sleeper":"false", "availCatCard": "false" } ] // 用户选中的筛选条件 const selectedCond = [{AC:'true'},{nonAC:'true'},{sleeper:'true'}] const result = universalMultiGroupFilter(sourceArray, selectedCond, FILTER_GROUPS) console.log(result.length) // 输出1,符合预期:仅第一条同时满足舒适度组匹配、座位组匹配
扩展性说明
- 新增分组时,仅需要在
FILTER_GROUPS配置中追加对应分组的字段列表,核心筛选逻辑无需任何修改。 - 完全消除了硬编码if-else分支,代码量不会随着分组数量增加而膨胀。
- 支持任意数量的分组叠加,所有逻辑都是通用遍历实现,不存在分支嵌套问题。
内容的提问来源于stack exchange,提问作者khristy_01
相关产品推荐
相关产品推荐

