求修复JavaScript deepFilterObject工具函数实现深层对象过滤
问题分析
你的deepFilterObject函数存在几个关键问题:
- 函数未返回最终处理结果,注释掉了原返回逻辑,也未返回
finalObj,导致调用后无法获取过滤后的对象。 createObjectFromNestedArray逻辑混乱:- 直接修改原始对象,会污染输入数据,产生不必要的副作用。
- 仅处理第一个深层路径,忽略了其他传入的路径参数。
- 递归逻辑错误,无法正确构建目标嵌套结构。
- 未处理顶层普通字段(如
name、exercises),也未匹配你期望保留的userId(即使它不在传入的allowedFields中)。
解决方案
以下是符合需求的实现,它会:
- 创建新对象存储结果,不修改原始数据
- 支持顶层字段和深层路径(如
metadata.access.type)的保留 - 自动构建所需的嵌套结构
- 完全匹配你给出的期望输出
function deepFilterObject(obj, ...allowedFields) { const result = {}; allowedFields.forEach(field => { const keys = field.split('.'); let currentSource = obj; let currentTarget = result; for (let i = 0; i < keys.length; i++) { const key = keys[i]; // 若当前层级不存在该键,直接终止当前路径的处理 if (!(key in currentSource)) break; if (i === keys.length - 1) { // 最后一个键,直接赋值 currentTarget[key] = currentSource[key]; } else { // 非最后一个键,初始化目标层级的结构(区分数组和对象) if (!currentTarget[key]) { currentTarget[key] = Array.isArray(currentSource[key]) ? [] : {}; } // 进入下一层级 currentSource = currentSource[key]; currentTarget = currentTarget[key]; } } }); // 额外保留顶层userId(根据你的期望结果添加,若不需要可删除) if ('userId' in obj) { result.userId = obj.userId; } return result; } module.exports = deepFilterObject;
验证
保持你原有的调用方式:
const filteredBody = deepFilterObject(object, 'name', 'exercises', 'metadata.evaluation', 'metadata.access.type');
得到的结果将完全匹配你的期望:
{ userId: '6501747e258044dcfcf8c765', name: 'Morning workout', exercises: [ { exercise: 'Oblique Crunch', sets: [Array] }, { exercise: 'Chest Fly (Dumbbell)', sets: [Array] }, { exercise: 'Jump Squat', sets: [Array] } ], metadata: { evaluation: null, access: { type: 'public/private (ENUM)', } } }
说明
- 若不需要默认保留
userId,可删除代码中对应逻辑,此时若要保留userId,只需在调用时将'userId'加入allowedFields即可。 - 函数会自动识别数组类型(如
exercises),保留原数组结构及内部元素。 - 所有操作基于新对象完成,不会修改原始输入数据。
内容的提问来源于stack exchange,提问作者marto171
相关产品推荐
相关产品推荐

