JavaScript如何实现支持数组对象的允许字段映射功能
问题根因
原有代码处理嵌套字段时,对非末尾层级的字段统一初始化为空对象{},没有适配数组类型的场景:当嵌套字段是数组时,不会遍历数组内的元素逐个做字段过滤,直接套用对象结构,因此无法正确处理数组内的嵌套对象。
修正后实现
核心逻辑调整:
- 增加类型判断,遇到数组类型的字段时,目标结构对应初始化为数组而非对象
- 对数组内的每个元素递归执行字段过滤,支持任意层级的对象/数组嵌套
- 增加空值兜底,避免null、undefined场景下的取值报错
function mapAllowedFields(allowedFields, data) { // 源数据为数组时,遍历每一项递归过滤 if (Array.isArray(data)) { return data.map(item => mapAllowedFields(allowedFields, item)) } // 源数据为基础类型/null时直接返回 if (typeof data !== 'object' || data === null) { return data } const result = {} allowedFields.forEach(fullPath => { const pathArr = fullPath.split('.') let sourceNode = data let targetNode = result for (let i = 0; i < pathArr.length; i++) { const key = pathArr[i] // 源数据无对应字段直接跳过当前路径 if (sourceNode?.[key] === undefined) break sourceNode = sourceNode[key] const isPathEnd = i === pathArr.length - 1 if (isPathEnd) { // 末尾节点直接赋值,若值为复杂类型自动递归过滤 const childFields = allowedFields .filter(path => path.startsWith(`${fullPath}.`)) .map(path => path.slice(fullPath.length + 1)) targetNode[key] = childFields.length ? mapAllowedFields(childFields, sourceNode) : sourceNode } else { const currentFullPath = pathArr.slice(0, i+1).join('.') // 按源数据类型初始化目标节点 if (targetNode[key] === undefined) { targetNode[key] = Array.isArray(sourceNode) ? [] : {} } // 处理数组类型节点 if (Array.isArray(sourceNode)) { const childFields = allowedFields .filter(path => path.startsWith(`${currentFullPath}.`)) .map(path => path.slice(currentFullPath.length + 1)) sourceNode.forEach((item, idx) => { targetNode[key][idx] = mapAllowedFields(childFields, item) }) break } } targetNode = targetNode[key] } }) return result }
效果验证
传入示例中的allowedFields和data调用该函数,返回结果完全符合预期:
- 顶层自动剔除
applied_at、rejected_at、last_activity_at等不在允许列表的字段 jobs数组中的每个对象仅保留id、name字段,自动移除email字段- 支持多层嵌套场景,无论是对象嵌套对象、对象嵌套数组、数组嵌套数组都可以正确过滤
内容的提问来源于stack exchange,提问作者mani kandan
相关产品推荐
相关产品推荐

