You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需递归移除对象及数组属性中的所有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 21:20:33