javascript - 从对象中移除空对象

标签 javascript node.js underscore.js

我正在尝试删除对象内的空对象,这是一个具有预期输出的示例:

var object = {
    a: {
        b: 1,
        c: {
            a: 1,
            d: {},
            e: {
              f: {} 
            }
        }
    },
    b: {}
}


var expectedResult = {
    a: {
        b: 1,
        c: {
            a: 1,
        }
    }
}

我尝试使用其他 StackOverflow 问题中的一些示例,但这些仅适用于一级对象。

最佳答案

移除空对象的基本函数

首先从一个只适用于单层嵌套的函数开始。

此函数删除所有引用空对象的属性:

function clearEmpties(o) {
  for (var k in o) {
    if (!o[k] || typeof o[k] !== "object") {
      continue // If null or not an object, skip to the next iteration
    }

    // The property is an object
    if (Object.keys(o[k]).length === 0) {
      delete o[k]; // The object had no properties, so delete that property
    }
    return o;
  }
}

使用递归处理嵌套对象

现在你想让它递归,以便它可以对嵌套对象进行操作。所以我们已经测试了 o[k] 是否是一个对象,并且我们已经测试了是否有属性,所以如果有,我们只需使用该嵌套对象再次调用该函数。

function clearEmpties(o) {
  for (var k in o) {
    if (!o[k] || typeof o[k] !== "object") {
      continue // If null or not an object, skip to the next iteration
    }

    // The property is an object
    clearEmpties(o[k]); // <-- Make a recursive call on the nested object
    if (Object.keys(o[k]).length === 0) {
      delete o[k]; // The object had no properties, so delete that property
    }
  }
    return o;
}

因此,就像对 clearEmpties 的原始调用会删除引用空对象的给定对象的属性一样,递归调用也会对嵌套对象执行相同的操作。


现场演示:

var object = {
  a: {
    b: 1,
    c: {
      a: 1,
      d: {},
      e: { // will need to be removed after f has been removed
         f: {} 
      }
    }
  },

  b: {}
};

clearEmpties(object);
console.log(object);

function clearEmpties(o) {
  for (var k in o) {
    if (!o[k] || typeof o[k] !== "object") {
      continue
    }

    clearEmpties(o[k]);
    if (Object.keys(o[k]).length === 0) {
      delete o[k];
    }
  }
  return o;
}


使用下划线和函数式风格的简短版本

function clearEmpties(o) {
  if (_.isFunction(o) || !_.isObject(o)) return o;
  return _.chain(o)
    .mapObject(clearEmpties)
    .pick(p => !(_.isObject(p) && _.isEmpty(p)))
    .value();
}

使用 lodash 和函数式风格的简短版本 - 适用于 treeshaking

import { isFunction, isObject, isEmpty, isArray, isPlainObject, fromPairs } from "lodash-es";

const removeEmtpyObjects = (o) => {
    if (isFunction(o) || !isPlainObject(o)) return o;

    if (isArray(o)) return o.map(removeEmtpyObjects);

    return fromPairs(
        Object.entries(o)
            .map(([k, v]) => [k, removeEmtpyObjects(v)])
            .filter(([k, v]) => !(v == null || (isObject(v) && isEmpty(v))))
    );
};

关于javascript - 从对象中移除空对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42736031/

相关文章:

javascript - 我可以在 mean.js 中的什么地方放置 CSS 文件?

node.js - openshift : Failed to execute: 'control restart' 上的 nodejs/postgresql

javascript - 创建随机整数的 JavaScript 数组

node.js - Nodejs Github api gist create - 接收Socket挂起

javascript - 包装多个 Backbone 渲染方法以避免 "before"和 "after"事件重复的优雅方法?

node.js - NodeJS 回调序列

javascript - 创建一个复制数组元素的按钮

javascript - amcharts 的问题

javascript - 如何让 jquery 在循环中的每个 ajax 调用后立即追加输出

javascript - 关于 window.open 的奇怪 Opera 问题