如何基于自定义配置递归删除JavaScript对象数组中的指定键名
问题描述
我自定义了dataFilter配置,希望基于该配置删除数据中的指定键:需要删除responseKeys数组中列明的键,以及ratings数组中列明的嵌套键。
目前我实现的逻辑只能删除顶层的指定键,无法对ratings数组内的嵌套对象键做过滤,请问是否可以通过递归解决该问题?
现有代码
let dataFilter = { "webPage1": { "responseKeys": ["releaseDate", "filmName"] }, "webPage2": { "responseKeys": ["releaseDate", "ratings"], "ratings": [ "star2", "star3" ] } } let data = [{ "filmName": "Avatar", "releaseDate": "2021-09-24", "day": "24", "month": "Sep", "ratings": [{ "star1": "40", "star2": "23", "star3": "56", "star4": "45" }, { "star1": "40", "star2": "23", "star3": "56", "star4": "45" }, { "star1": "40", "star2": "23", "star3": "56", "star4": "45" } ] }, { "filmName": "Morgan", "releaseDate": "2021-03-24", "day": "24", "month": "Mar", "ratings": [{ "star1": "40", "star2": "23", "star3": "56", "star4": "45" }, { "star1": "40", "star2": "23", "star3": "56", "star4": "45" }, { "star1": "40", "star2": "23", "star3": "56", "star4": "45" } ] } ] const filterResponse = (data, dataFilter = '') => { if (dataFilter) { let filterArray = []; data.forEach((item) => { let response = Object.keys(item) .filter(key => dataFilter.responseKeys.includes(key)) .reduce((obj, key) => { obj[key] = item[key]; return obj; }, {}); filterArray.push(response); }); return filterArray; } return data; }; console.log(filterResponse(data, dataFilter['webPage1']));
期望输出
//webPage1 [{ "filmName": "Avatar", "releaseDate": "2021-09-24" }, { "filmName": "Morgan", "releaseDate": "2021-03-24" } ] //webPage2 [{ "releaseDate": "2021-09-24", "ratings": [{ "star2": "23", "star3": "56" }, { "star2": "23", "star3": "56" }, { "star2": "23", "star3": "56" } ] }, { "releaseDate": "2021-03-24", "ratings": [{ "star2": "23", "star3": "56" }, { "star2": "23", "star3": "56" }, { "star2": "23", "star3": "56" }] }]
解决方案
可以通过递归实现嵌套层级的键过滤,修改后的实现如下:
const filterResponse = (data, dataFilter = '') => { if (!dataFilter) return data; // 过滤单个对象 const filterObj = (obj, rule) => { return Object.keys(obj) .filter(key => rule.responseKeys.includes(key)) .reduce((res, key) => { // 存在对应子字段过滤规则、且当前值为数组时递归过滤 if (Array.isArray(obj[key]) && rule[key]) { res[key] = obj[key].map(child => { return Object.keys(child) .filter(childKey => rule[key].includes(childKey)) .reduce((childRes, childKey) => { childRes[childKey] = child[childKey]; return childRes; }, {}) }) } else { res[key] = obj[key] } return res; }, {}) } return data.map(item => filterObj(item, dataFilter)) }; // 测试调用 console.log(filterResponse(data, dataFilter['webPage1'])) console.log(filterResponse(data, dataFilter['webPage2']))
上述代码完全匹配期望输出,后续如果需要支持更深层级的嵌套,只要扩展递归判断逻辑即可。
内容的提问来源于stack exchange,提问作者xMayank
相关产品推荐
相关产品推荐

