JavaScript嵌套数组JSON过滤异常及二次搜索实现求助
解决嵌套分类搜索过滤及原数组修改问题
核心问题拆解
- 仅保留包含匹配子分类的父分类,且父分类下只保留匹配的子项
- 避免搜索操作修改原数组,确保后续搜索可正常执行
解决方案实现
1. 避免修改原数组:深拷贝原数据
JavaScript中对象/数组是引用类型,直接操作会修改原数据。每次搜索时基于原数据的独立副本操作,保证原数据不受影响。对于纯JSON结构的数据,用JSON.parse(JSON.stringify())实现深拷贝最便捷。
2. 正确的过滤逻辑
遍历父分类,对每个分类的子分类进行关键词匹配:
- 筛选出名称包含关键词的子项
- 若存在匹配子项,则保留该父分类,并将其子分类列表替换为匹配结果
- 无匹配子项的父分类直接排除
完整代码示例
// 示例原数据(API返回的多级分类结构) const originalCategories = [ { id: 1, name: "Electronics", subcategories: [ { id: 11, name: "Laptops" }, { id: 12, name: "Smartphones" }, { id: 13, name: "Technology Accessories" } ] }, { id: 2, name: "Home", subcategories: [ { id: 21, name: "Furniture" }, { id: 22, name: "Kitchen Appliances" } ] } ]; // 搜索过滤函数 function filterCategories(keyword, originalData) { // 深拷贝原数据,完全隔离原数组 const dataCopy = JSON.parse(JSON.stringify(originalData)); // 空关键词返回完整数据副本 if (!keyword.trim()) { return dataCopy; } const lowerKeyword = keyword.toLowerCase(); return dataCopy.filter(category => { // 过滤当前分类下匹配的子项(大小写不敏感) const matchedSubcats = category.subcategories.filter(subcat => subcat.name.toLowerCase().includes(lowerKeyword) ); // 有匹配子项则保留父分类并更新子项列表 if (matchedSubcats.length > 0) { category.subcategories = matchedSubcats; return true; } // 无匹配则排除该父分类 return false; }); } // 测试:搜索关键词"tec" const result = filterCategories("tec", originalCategories); console.log(result); // 输出结果: // [ // { // id: 1, // name: "Electronics", // subcategories: [ { id: 13, name: "Technology Accessories" } ] // } // ]
处理更深层次的嵌套分类
如果你的分类结构有三级及以上嵌套(子分类还有子分类),可以改用递归过滤逻辑:
// 递归过滤嵌套子分类 function filterNestedSubcats(subcats, keyword) { const lowerKeyword = keyword.toLowerCase(); return subcats.filter(subcat => { // 检查当前子项是否匹配 const isMatch = subcat.name.toLowerCase().includes(lowerKeyword); // 递归处理子分类的子分类 if (subcat.subcategories?.length) { const filteredChildren = filterNestedSubcats(subcat.subcategories, keyword); if (filteredChildren.length) { subcat.subcategories = filteredChildren; return true; } } // 保留当前匹配的项,或包含匹配子项的项 return isMatch; }); } // 修改后的filterCategories函数 function filterCategories(keyword, originalData) { const dataCopy = JSON.parse(JSON.stringify(originalData)); if (!keyword.trim()) return dataCopy; return dataCopy.filter(category => { const matchedSubcats = filterNestedSubcats(category.subcategories, keyword); if (matchedSubcats.length) { category.subcategories = matchedSubcats; return true; } return false; }); }
内容的提问来源于stack exchange,提问作者Mohit Kumar Sharma
相关产品推荐
相关产品推荐

