JS中基于预定义规则筛选排序JSON对象数组的实现求助
问题解决思路与实现代码
一、核心问题分析
你的代码存在几个关键问题:
- 筛选逻辑硬编码了
name字段,无法适配任意键值的筛选规则 - 排序时错误地把字符串
"sort_by"传给比较器,而不是实际的字段名 - 函数参数设计混乱,没有对应上
include/exclude的条件格式 - 直接修改原数组
data,不符合函数式编程的最佳实践(应该返回新数组)
二、分步实现方案
1. 筛选逻辑实现
支持**包含(include)和排除(exclude)**两种规则,且能处理多键值的筛选条件:
- 包含规则:对象必须匹配所有指定的键值对
- 排除规则:对象不能匹配任何指定的键值对
// 检查单个对象是否匹配一组键值条件 function matchesConditions(obj, conditions) { return conditions.every(cond => { const [key, value] = Object.entries(cond)[0]; return obj[key] === value; }); } // 筛选函数 function filterData(data, condition) { let filtered = [...data]; // 复制原数组,避免修改原数据 if (condition.include) { filtered = filtered.filter(obj => matchesConditions(obj, condition.include)); } if (condition.exclude) { filtered = filtered.filter(obj => !matchesConditions(obj, condition.exclude)); } return filtered; }
2. 自然排序逻辑实现
支持按多个字段排序(比如先按name,再按email),自然排序遵循字符串的字典序:
// 生成多字段比较器 function createSortComparator(sortFields) { return (a, b) => { for (const field of sortFields) { if (a[field] < b[field]) return -1; if (a[field] > b[field]) return 1; } return 0; // 所有字段都相等时返回0 }; } // 排序函数 function sortData(data, sortFields) { if (!sortFields || sortFields.length === 0) return [...data]; return [...data].sort(createSortComparator(sortFields)); }
3. 整合筛选与排序的主函数
把筛选和排序逻辑结合,适配你定义的条件格式:
function processData(rawData, condition) { const dataArray = rawData.data || rawData; // 兼容外层带data键的结构 // 先筛选 const filtered = filterData(dataArray, condition); // 再排序 const sorted = sortData(filtered, condition.sortBy || condition.sort_by); // 兼容两种字段名拼写 return sorted; }
三、完整测试示例
测试数据与条件
// 示例数据 const sampleData = { "data": [ {"name": "Peter", "email": "pet2@mail.com"}, {"name": "Peter", "email": "pet1@mail.com"}, {"name": "Marge", "email": "marge@mail.com"} ] }; // 包含条件测试 const includeCondition = { "include": [{"name": "Peter"}], "sortBy": ["email"] }; // 排除条件测试 const excludeCondition = { "exclude": [{"name": "Marge"}], "sort_by": ["email"] };
执行测试
// 执行包含筛选+排序 const includeResult = processData(sampleData, includeCondition); console.log("包含筛选结果:", includeResult); // 输出:[{"name":"Peter","email":"pet1@mail.com"},{"name":"Peter","email":"pet2@mail.com"}] // 执行排除筛选+排序 const excludeResult = processData(sampleData, excludeCondition); console.log("排除筛选结果:", excludeResult); // 输出:[{"name":"Peter","email":"pet1@mail.com"},{"name":"Peter","email":"pet2@mail.com"},{"name":"Marge","email":"marge@mail.com"}]
四、关键知识点说明
filter():返回新数组,不会修改原数组,适合做筛选操作sort():会直接修改原数组,所以排序前要先复制数组([...data])- 自然排序:字符串默认的比较逻辑就是字典序(自然排序),直接用
<和>即可 - 多字段排序:依次比较每个字段,前面的字段相等时才比较下一个字段
内容的提问来源于stack exchange,提问作者Dis pi s
相关产品推荐
相关产品推荐

