递归从对象中删除空键/值对的最佳方法

时间:2018-12-14 09:30:46

标签: javascript recursion

假设我有当前数据对象:

const human = {
  name: '',
  age: 0,
  head: {
    rightEye: '',
    leftEye: '',
  }
  limbs: {
    arms: '',
    legs: '',
  }
  somethingElse: '',
}

我想删除每个空键/值对。而这部分我可以使用以下代码进行操作:

const removeFalsy = (obj) => {
  const newObj = {};
  Object.keys(obj).forEach((prop) => {
    if (obj[prop]) {
      if (typeof obj[prop] === 'object') {
        newObj[prop] = removeFalsy(obj[prop]);
      } else {
        newObj[prop] = obj[prop];
      }
    }
  });
  return newObj;
};

事情是空的对象仍然停留在主对象中。我想从主对象中删除所有空对象,以获得以下结果:

const human = {};

代替我当前的结果:

const human = {
  head: {},
  limbs: {},
}

我最好的选择是什么?

2 个答案:

答案 0 :(得分:2)

在递归调用removeFalsy时,仅当递归调用的结果具有一个至少带有一个键的对象时,才分配给newObj

const removeFalsy = (obj) => {
  const newObj = {};
  Object.keys(obj).forEach((prop) => {
    if (obj[prop]) {
      if (typeof obj[prop] === 'object') {

        // change below:
        const nonFalseyVal = removeFalsy(obj[prop]);
        if (Object.keys(nonFalseyVal).length !== 0) {
          newObj[prop] = nonFalseyVal;
        }
        // change above

      } else {
        newObj[prop] = obj[prop];
      }
    }
  });
  return newObj;
};

const human = {
  name: '',
  age: 0,
  head: {
    rightEye: '',
    leftEye: '',
  },
  limbs: {
    arms: '',
    legs: '',
  },
  somethingElse: '',
}
const nonFalsyHuman = removeFalsy(human);
console.log(nonFalsyHuman);

请注意,使用.reduce可能更合适,您可以使用Object.entries立即获取键

const removeFalsy = (obj) => {
  return Object.entries(obj).reduce((a, [key, val]) => {
    if (!val) return a;
    if (typeof val === 'object') {
      const nonFalseyVal = removeFalsy(val);
      if (Object.keys(nonFalseyVal).length !== 0) {
        a[key] = nonFalseyVal;
      }
    } else {
      a[key] = obj[key];
    }
    return a;
  }, {});
};

const human = {
  name: '',
  age: 0,
  head: {
    rightEye: '',
    leftEye: '',
  },
  limbs: {
    arms: '',
    legs: '',
  },
  somethingElse: '',
}
const nonFalsyHuman = removeFalsy(human);
console.log(nonFalsyHuman);

答案 1 :(得分:2)

您需要进行以下更改

  • 更新if (typeof obj[prop] === 'object') {条件,仅在对象具有一些有效键的情况下设置值。
  • 更新if (obj[prop]) {条件以允许其他非伪造的值进入循环,例如0等

const human = {name: '',age: 0,head: {rightEye: '',leftEye: ''},limbs: {arms: '',legs: ''},somethingElse: ''};

const removeFalsy = (obj) => {
  const newObj = {};
  Object.keys(obj).forEach((prop) => {
    if (obj[prop] !== "") {
      if (typeof obj[prop] === 'object') {
        const temp = removeFalsy(obj[prop]);
        if(Object.keys(temp).length) newObj[prop] = temp;
      } else {
        newObj[prop] = obj[prop];
      }
    }
  });
  return newObj;
};

console.log(removeFalsy(human));