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

如何移除JSON中的空白字段?现有代码问题及优化需求

问题排查与解决方案

咱们先把原代码里的问题一个个揪出来,再给出修复后的版本,最后实现不修改原对象的清理逻辑。

一、原代码的核心问题

你的代码里有好几处关键错误,导致空对象/数组没法被移除:

  1. 函数名拼写错误:你定义了判断空白的函数isBlank,但递归时却用了isEmpty,这直接导致判断逻辑完全失效。
  2. 变量名笔误:jsonInput[key_field]里的key_field是个未定义的变量,应该写成jsonInput[key]。
  3. 空对象判断逻辑缺失:原isBlank函数里,对象没有length属性,所以val.length === 0对空对象会返回false,根本识别不了空对象。
  4. 递归后未校验空值:就算递归清理了子对象里的空白字段,原代码也没检查清理后的子对象/数组是不是变成空的了,所以空的allBlanks数组、att2对象才会留在结果里。
  5. 数组元素处理遗漏:原代码没考虑数组里的元素清理,比如数组里的空对象应该被移除,而不是留在数组里变成[{ }]。

二、修复修改原对象的版本

先完善空白判断函数,再修正递归逻辑,处理数组和对象的所有情况:

// 完善空白字段判断:覆盖null、空白字符串、空数组、空对象
const isBlank = (val) => {
  if (val === null) return true;
  if (typeof val === 'string') return val.trim().length === 0;
  if (Array.isArray(val)) return val.length === 0;
  if (typeof val === 'object') return Object.keys(val).length === 0;
  return false;
};

function clean(jsonInput) {
  // 先处理数组:从后往前删,避免索引错乱
  if (Array.isArray(jsonInput)) {
    for (let i = jsonInput.length - 1; i >= 0; i--) {
      const item = jsonInput[i];
      if (typeof item === 'object' && item !== null) {
        clean(item);
        // 递归后如果元素变成空白,直接移除
        if (isBlank(item)) {
          jsonInput.splice(i, 1);
        }
      } else if (isBlank(item)) {
        jsonInput.splice(i, 1);
      }
    }
    return;
  }

  // 处理对象:遍历所有键,递归清理后再判断是否删除
  Object.keys(jsonInput).forEach(key => {
    const val = jsonInput[key];
    if (typeof val === 'object' && val !== null) {
      clean(val);
      // 子对象/数组清理后变空白,删除这个键
      if (isBlank(val)) {
        delete jsonInput[key];
      }
    } else if (isBlank(val)) {
      delete jsonInput[key];
    }
  });
}

测试这段代码,传入你的输入数据,就能得到预期的输出:

const input = { 
  "print": "notBlank", 
  "this": "notBlank", 
  "example": "notBlank", 
  "blank": null, 
  "allBlanks": [ { "from": "", "blank0": null } ], 
  "att2": { "blank1": "", "blank2": [] }, 
  "att3": { "one": "1", "two": "2", "three": "3", "blank3": " " } 
};

clean(input);
console.log(JSON.stringify(input, null, 2));
// 输出和预期完全一致

三、不修改原对象,生成副本的版本

如果不想改动原数据,我们可以创建一个新的对象/数组,递归处理每个元素,只保留非空白内容:

const isBlank = (val) => {
  if (val === null) return true;
  if (typeof val === 'string') return val.trim().length === 0;
  if (Array.isArray(val)) return val.length === 0;
  if (typeof val === 'object') return Object.keys(val).length === 0;
  return false;
};

function cleanCopy(jsonInput) {
  // 处理数组:先递归处理每个元素,再过滤空白项
  if (Array.isArray(jsonInput)) {
    return jsonInput
      .map(item => typeof item === 'object' && item !== null ? cleanCopy(item) : item)
      .filter(item => !isBlank(item));
  }

  // 处理对象:创建新对象,只保留清理后非空白的键值对
  if (typeof jsonInput === 'object' && jsonInput !== null) {
    const cleanedObj = {};
    Object.keys(jsonInput).forEach(key => {
      const val = jsonInput[key];
      const cleanedVal = typeof val === 'object' && val !== null ? cleanCopy(val) : val;
      if (!isBlank(cleanedVal)) {
        cleanedObj[key] = cleanedVal;
      }
    });
    return cleanedObj;
  }

  // 非对象/数组类型直接返回
  return jsonInput;
}

使用这个版本时,原对象会完全保留,返回的是全新的清理后的数据:

const input = { /* 你的输入数据 */ };
const cleanedResult = cleanCopy(input);
// input 保持不变,cleanedResult 是预期的输出

为什么这样改?

  • 完善后的isBlank函数覆盖了所有你定义的空白字段类型,不会漏掉空对象。
  • 处理数组时从后往前删除元素,避免因为索引变化导致的漏删。
  • 副本版本通过map和filter处理数组,通过创建新对象处理对象,完全没有副作用,适合需要保留原数据的场景。

内容的提问来源于stack exchange,提问作者lokilindo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:07:59