如何实现仅保留有子元素父元素的JavaScript数组处理逻辑
筛选拥有子元素的分类节点
没问题,我来帮你实现这个筛选逻辑!先理清楚需求:我们需要从给定的父-子结构分类数据中,只保留那些有子元素的父分类——也就是,只要有其他分类把它的ID作为parent值,就把它留下来,否则过滤掉。
我手头有一个父-子结构的JavaScript对象,格式如下:
const categories = { "data": { "1": { "id": 1, "name": "Churches & Religious Org.", "description": "Church/religious organization", "parent": 267, "icon": "home" }, "2": { "id": 2, "name": "Bands & Musicians", "description": "Musician/band", "parent": 259, "icon": "music-note" }, "3": { "id": 3, "name": "Products & Services", "description": "Product/service", "parent": 260, "icon": "cube" }, "4": { "id": 4, "name": "Actors & Directors", "description": "Actor/director", "parent": 256, "icon": "film-marker" }, "5": { "id": 5, "name": "Athletes & Players", "description": "Athlete", "parent": 264, "icon": "ios-americanfootball" }, "6": { "id": 6, "name": "Movies", "description": "Movie", "parent": 256, "icon": "ios-film" }, "7": { "id": 7, "name": "TV Shows", "description": "TV show", "parent": 256, "icon": "ios-videocam" }, "8": { "id": 8, "name": "Professional Teams", "description": "Sports Team", "parent": 264, "icon": "" }, "9": { "id": 9, "name": "Politicians", "description": "Politician", "parent": 263, "icon": "" }, "10": { "id": 10, "name": "Food Products", "description": "Food & Beverage Company", "parent": 258, "icon": "" } } };
实现思路
这个需求其实可以拆成两步简单完成:
- 先收集所有被当作父级的ID:遍历所有分类,把每个分类的
parent值都存起来——这些ID就是有子元素的父分类ID。 - 筛选出符合条件的分类:再遍历一次所有分类,只保留那些
id在第一步收集的ID集合里的分类,因为这说明它们至少有一个子分类。
代码实现
返回数组格式的结果
如果希望结果是一个包含符合条件分类的数组,可以用这个函数:
function filterParentCategories(categoriesData) { // 第一步:用Set存储所有被引用的父ID,查询效率更高 const parentIds = new Set(); Object.values(categoriesData.data).forEach(category => { parentIds.add(category.parent); }); // 第二步:筛选出ID在父ID集合中的分类 const filteredCategories = Object.values(categoriesData.data).filter(category => { return parentIds.has(category.id); }); return filteredCategories; } // 调用示例 const resultArray = filterParentCategories(categories); console.log(resultArray);
返回原对象格式的结果
如果你需要保持和输入一致的对象结构(而不是数组),可以用这个版本:
function filterParentCategoriesAsObject(categoriesData) { const parentIds = new Set(); Object.values(categoriesData.data).forEach(category => { parentIds.add(category.parent); }); const filteredData = {}; // 遍历原对象的键值对,保留符合条件的分类 Object.entries(categoriesData.data).forEach(([key, category]) => { if (parentIds.has(category.id)) { filteredData[key] = category; } }); return { data: filteredData }; } // 调用示例 const resultObject = filterParentCategoriesAsObject(categories); console.log(resultObject);
代码说明
- 用
Set而不是数组来存父ID,是因为Set.has()的查询速度是O(1),比数组的includes()(O(n))高效得多,尤其是当分类数量很大的时候。 - 两次遍历的时间复杂度是O(n),整体性能非常好,适合处理大量数据。
针对示例输入的输出
运行上面的函数后,结果会包含以下两个分类:
- ID 256(因为它是分类4、6、7的父级)
- ID 264(因为它是分类5、8的父级)
其他分类(比如1、2、3等)没有子元素引用它们的ID,所以会被过滤掉。
内容的提问来源于stack exchange,提问作者tushersuvro
相关产品推荐
相关产品推荐

