如何从对象集合中提取最详细的唯一层级对象?
问题
我有一个存储公司层级选择的对象集合,示例如下:
{ 1: { division: "division1" }, 2: { division: "division2" }, 11: { division: "division2", branch: "branch2" }, 41: { division: "division2", branch: "branch2", department: "department2" }, 100: { division: "division2", branch: "branch2", department: "department10" }, 102: { division: "division2", branch: "branch3" }, 130: { division: "division17" }, 144: { division: "division17" , branch: "branch22" }, 200: { division: "division50" } }
需要从中提取唯一且最详细的对象,预期结果如下(无需保留原键):
{ 1: { division: "division1" }, 41: { division: "division2", branch: "branch2", department: "department2" }, 100: { division: "division2", branch: "branch2", department: "department10" }, 102: { division: "division2", branch: "branch3" }, 144: { division: "division17" , branch: "branch22" }, 200: { division: "division50" } }
这些数据来自三个下拉框的选择,层级关系为division > branch > department。比如用户先选division2再选branch2,会同时添加{ division: "division2" }和{ division: "division2", branch: "branch2" },但只需要最详细的后者。
解决方案
可以用JavaScript实现这个筛选逻辑,核心思路是过滤掉所有被其他层级更深的对象完全包含的项,具体代码如下:
const input = { 1: { division: "division1" }, 2: { division: "division2" }, 11: { division: "division2", branch: "branch2" }, 41: { division: "division2", branch: "branch2", department: "department2" }, 100: { division: "division2", branch: "branch2", department: "department10" }, 102: { division: "division2", branch: "branch3" }, 130: { division: "division17" }, 144: { division: "division17" , branch: "branch22" }, 200: { division: "division50" } }; // 把输入对象转成值数组(不需要原键) const items = Object.values(input); // 筛选出最详细的项:排除所有被其他层级更深的对象包含的项 const detailedItems = items.filter(item => { return !items.some(other => { if (item === other) return false; // 检查当前项的所有字段值都和other匹配 const allFieldsMatch = Object.keys(item).every(key => other[key] === item[key]); // 检查other的字段数比当前项多(层级更深) const hasMoreDetails = Object.keys(other).length > Object.keys(item).length; return allFieldsMatch && hasMoreDetails; }); }); // 可选:把结果转回对象(键可以自定义,这里用索引) const resultObj = detailedItems.reduce((acc, item, idx) => { acc[idx + 1] = item; return acc; }, {}); console.log(resultObj);
逻辑说明
- 转数组:先用
Object.values把输入对象转成只包含层级数据的数组,抛弃原键。 - 筛选核心:
- 对每个项,用
some检查是否存在另一个对象:既完全匹配当前项的所有字段值,又有更多的字段(意味着层级更深、信息更详细)。 - 如果存在这样的对象,说明当前项是冗余的,直接过滤掉;否则保留。
- 对每个项,用
- 转回对象(可选):如果需要对象格式,用
reduce把筛选后的数组转回对象,键可以根据需求自定义(比如索引、层级字段拼接的唯一标识)。
内容的提问来源于stack exchange,提问作者pileup
相关产品推荐
相关产品推荐

