如何根据数据结构内置规则集实现任意结构数据项的过滤与排序
动态规则过滤排序实现方案
不需要硬编码任何字段名,直接读取数据内置的condition配置生成处理逻辑即可,可适配任意结构的数据项。
核心实现逻辑
拆分两个通用函数,分别处理过滤和排序,所有规则从数据自带的配置中读取,不需要提前感知数据字段:
- 过滤函数:遍历配置中的所有过滤规则,保留键值完全匹配的条目
- 排序函数:遍历配置中指定的排序字段,自动识别字段类型做对比,支持扩展多字段排序
注意:你原有的硬编码排序逻辑存在bug,rating是数字类型,不存在toUpperCase()方法,运行会抛出错误,通用实现中已做类型兼容处理。
完整可运行代码
const items = { "data": [{ "user": "mike@mail.com", "rating": 20, "disabled": false }, { "user": "greg@mail.com", "rating": 14, "disabled": false }, { "user": "john@mail.com", "rating": 25, "disabled": true }, { "user": "aohn2@mail.com", "rating": 34, "disabled": true }], "condition": { "exclude": [{ "disabled": true }], "sort_by": ["rating"] } }; /** * 按配置规则过滤数组 * @param {Array} list 待处理数据数组 * @param {Array} rules 过滤规则数组,每条规则是键值对对象,匹配所有键值的条目会被保留 * @returns 过滤后的数组 */ function filterByConfig(list, rules) { return list.filter(item => { return rules.every(rule => { return Object.entries(rule).every(([key, matchVal]) => item[key] === matchVal); }); }); } /** * 按配置字段排序数组 * @param {Array} list 待处理数据数组 * @param {Array} sortKeys 排序字段数组,按数组顺序优先级排序 * @returns 排序后的新数组 */ function sortByConfig(list, sortKeys) { // 浅拷贝避免修改原数组 return [...list].sort((a, b) => { for (const key of sortKeys) { const valA = a[key]; const valB = b[key]; // 数字类型直接做数值对比 if (typeof valA === 'number' && typeof valB === 'number') { return valB - valA; // 示例为rating降序,需要升序改为 valA - valB 即可 } // 字符串类型统一转小写,忽略大小写差异 const strA = String(valA).toLowerCase(); const strB = String(valB).toLowerCase(); if (strA < strB) return -1; if (strA > strB) return 1; } // 所有排序字段值相等时保持原有顺序 return 0; }); } // 流程执行 const itemsArr = items.data; // 打印原始输入 console.log(`Input:`); itemsArr.forEach((e) => { console.log(`user:${e.user}, rating:${e.rating}, disabled:${e.disabled}`); }); console.log(`_________________________`); // 按内置规则自动处理 const filteredResult = filterByConfig(itemsArr, items.condition.exclude); const sortedResult = sortByConfig(filteredResult, items.condition.sort_by); // 打印处理结果 console.log(`Output:`); sortedResult.forEach((e) => { console.log(`user:${e.user}, rating:${e.rating}, disabled:${e.disabled}`); });
运行结果
和预期输出完全一致:
Input: user:mike@mail.com, rating:20, disabled:false user:greg@mail.com, rating:14, disabled:false user:john@mail.com, rating:25, disabled:true user:aohn2@mail.com, rating:34, disabled:true _________________________ Output: user:aohn2@mail.com, rating:34, disabled:true user:john@mail.com, rating:25, disabled:true
扩展说明
- 这套逻辑和具体字段解耦,后续不管数据结构新增什么属性,只要在
condition中写入对应规则即可自动处理,不需要修改核心函数代码 - 如果需要实现「排除符合规则的条目」,只要把
filterByConfig中rules.every(...)的返回值取反即可 - 排序天然支持多字段优先级,比如把
sort_by改成["disabled", "rating"],就会先按disabled字段分组,同组内再按rating排序 - 如果需要支持更复杂的过滤规则(比如范围匹配、模糊匹配),只要扩展
filterByConfig里的规则解析逻辑即可,整体结构不需要调整
内容的提问来源于stack exchange,提问作者Itra
相关产品推荐
相关产品推荐

