如何无需递归移除对象及数组属性中的所有undefined值?
清除对象中所有
undefined字段的简化方案 一、Lodash 简洁实现(无需手动递归)
你之前用_.transform的写法只处理了顶层对象,还会误过滤0、''等假值。可以用_.cloneDeepWith递归遍历所有嵌套结构,结合_.omitBy精准移除undefined字段:
const cleanedFields = _.cloneDeepWith(fields, (value) => { // 处理普通对象:移除值为undefined的键 if (_.isPlainObject(value)) { return _.omitBy(value, _.isUndefined); } // 数组会自动递归处理内部元素,无需额外操作 });
这个写法会自动处理嵌套对象和数组,比如你的steps数组里的第二个对象,会移除childrenIds: undefined字段,同时保留整个数组结构。
二、原生JS简化递归实现
你原来的递归函数没处理数组场景(会把数组转换成对象),下面是修正后的简化版本,同时支持对象和数组:
function compactObject(obj) { // 处理数组:递归处理每个元素,过滤掉undefined if (Array.isArray(obj)) { return obj.map(compactObject).filter(item => item !== undefined); } // 处理非数组对象:过滤undefined字段,递归处理嵌套值 if (typeof obj === 'object' && obj !== null) { return Object.fromEntries( Object.entries(obj) .map(([key, val]) => [key, compactObject(val)]) .filter(([_, val]) => val !== undefined && !(typeof val === 'object' && Object.keys(val).length === 0)) ); } // 原始类型直接返回 return obj; } // 使用示例 const cleanedFields = compactObject(fields);
三、非递归迭代实现(无需递归函数)
如果一定要避免递归,可通过栈遍历所有嵌套结构,手动处理每个层级:
function compactObjectIterative(obj) { const root = Array.isArray(obj) ? [...obj] : {...obj}; // 栈元素存储父级、当前键、当前目标对象、原始对象 const stack = [{ parent: null, key: null, target: root, original: obj }]; while (stack.length) { const { parent, key, target, original } = stack.pop(); if (Array.isArray(target)) { // 倒序遍历数组,避免删除元素时索引错乱 for (let i = target.length - 1; i >= 0; i--) { const origVal = original[i]; if (typeof origVal === 'object' && origVal !== null) { const newTarget = Array.isArray(origVal) ? [...origVal] : {...origVal}; target[i] = newTarget; stack.push({ parent: target, key: i, target: newTarget, original: origVal }); } else if (origVal === undefined) { target.splice(i, 1); } } // 处理空数组:如果父级存在则删除 if (target.length === 0 && parent !== null) { Array.isArray(parent) ? parent.splice(key, 1) : delete parent[key]; } } else if (typeof target === 'object' && target !== null) { for (const k of Object.keys(target)) { const origVal = original[k]; if (typeof origVal === 'object' && origVal !== null) { const newTarget = Array.isArray(origVal) ? [...origVal] : {...origVal}; target[k] = newTarget; stack.push({ parent: target, key: k, target: newTarget, original: origVal }); } else if (origVal === undefined) { delete target[k]; } } // 处理空对象:如果父级存在则删除 if (Object.keys(target).length === 0 && parent !== null) { Array.isArray(parent) ? parent.splice(key, 1) : delete parent[key]; } } } return root; } // 使用示例 const cleanedFields = compactObjectIterative(fields);
内容的提问来源于stack exchange,提问作者Jincheol Park
相关产品推荐
相关产品推荐

