JavaScript:如何用filter过滤children为空的JSON对象?
问题
需要过滤JSON结构中所有children为空数组的对象。目前能通过forEach循环识别出这类空对象,但不知道如何用filter函数实现相同的过滤效果(过滤条件依赖对象的children属性)。以提供的json_data为例,需要过滤掉children为空的NEWMAR对象。
原始测试代码:
var testF = json_data.children.forEach(obj => { if (obj.children.length != 0) { obj.children.forEach( obj => { if (obj.children.length != 0) { console.log(obj) } else { console.log("EMPTY") } }) } }); json_data = { "name": "WINNEBAGO", "description": "", "free": true, "url": "https://www.winnebago.com/", "children": [{ "name": "WINNEBAGO", "description": "", "url": "https://www.winnebago.com/", "free": true, "children": [{ "name": "ADVENTURER", "description": "CLASS A", "url": "https://www.winnebago.com/models/product/motorhomes/class-a/adventurer", "free": true, "type": "5" }, { "name": "ADVENTURER AE", "description": "CLASS A", "url": "https://www.winnebago.com/models/product/motorhomes/accessibility-enhanced/adventurer-ae", "free": true, "type": "5" } ] }, { "name": "GRAND DESIGN RV", "description": "", "url": "https://www.granddesignrv.com/", "free": true, "children": [{ "name": "TRANSCEND XPLOR", "description": "TRAVEL TRAILER", "url": "https://www.granddesignrv.com/showroom/2022/travel-trailer/transcend-xplor", "free": true, "type": "2" }, { "name": "IMAGINE", "description": "TRAVEL TRAILER", "url": "https://www.granddesignrv.com/showroom/2022/travel-trailer/imagine", "free": true, "type": "2" } ] }, { "name": "NEWMAR", "description": "", "url": "https://www.newmarcorp.com/", "free": true, "children": [] } ] }
解决方案
针对当前层级的过滤
如果只需要处理json_data.children这一层级,直接使用filter函数即可,判断条件为对象的children数组长度大于0:
// 过滤json_data的children,移除children为空的对象 json_data.children = json_data.children.filter(item => item.children.length > 0); console.log(json_data);
执行后,NEWMAR对象会被完全过滤,剩下的子节点只有WINNEBAGO和GRAND DESIGN RV。
递归处理多层嵌套结构
如果你的JSON存在多层嵌套的children,需要递归过滤每一层中children为空的对象,可以使用以下递归函数:
function removeEmptyChildNodes(node) { // 若当前节点没有children属性,直接返回 if (!node.children) return node; // 过滤当前节点的children,保留children非空的节点,同时递归处理子节点的children node.children = node.children .filter(child => child.children && child.children.length > 0) .map(child => removeEmptyChildNodes(child)); return node; } // 处理整个JSON数据 const filteredData = removeEmptyChildNodes(json_data); console.log(filteredData);
为什么filter比forEach更合适
你之前的forEach代码仅能识别空对象并打印日志,但不会修改原数据结构。而filter会直接返回符合条件的新数组,将其赋值回原对象的children属性即可完成过滤,代码更简洁且符合函数式编程的思路。
内容的提问来源于stack exchange,提问作者Joseph Dain
相关产品推荐
相关产品推荐

