首页 > 解决方案 > 如何从对象中删除未定义的属性和从数组中删除元素

问题描述

我有以下对象:

{
  a: {
    b: {
      c: undefined
    }
  },
  b: {
    c: 15,
    d: []
  },
  c: {
    d: [11, undefined ,12],
    e: {}
  }
}

我需要得到这个:

{
 b: {
  c: 15
 },
 c: {
  d: [11, 12]
 }
}

我找到了这个函数(来源:从对象中删除未定义的属性

function filter(obj) {
  for (var key in obj) {
    if (obj[key] === undefined) {
      delete obj[key];
      continue;
    }
    if (obj[key] && typeof obj[key] === "object") {
      filter(obj[key]);
      if (!Object.keys(obj[key]).length) {
        delete obj[key];
      }
    }
  }
  return obj;
}

但它只是删除数组的元素,结果如下

{
 b: {
  c: 15
 },
 c: {
  d: [11, empty ,12]
 }
}

标签: javascript

解决方案


您需要一个递归解决方案。创建一个函数,如果它的值是假的,或者它的所有递归元素都是假的或空数组或没有键,则它接受一个值并返回假的东西:

const removeRecursive = (obj) => {
  // Falsey primitive, including null:
  if (!obj) return;
  // Truthy primitive (or function):
  if (typeof obj !== 'object') return obj;
  // Array, transform all values and return the new array
  // if there are any truthy transformed values:
  if (Array.isArray(obj)) {
    const newArr = obj.map(removeRecursive).filter(Boolean);
    return newArr.length ? newArr : undefined;
  }
  // Otherwise, it's an object:
  const newObj = Object.fromEntries(
    Object.entries(obj)
      .map(([key, val]) => ([key, removeRecursive(val)]))
      .filter(([, val]) => val)
  );
  if (Object.keys(newObj).length) {
    return newObj;
  }
};

const obj = {
  a: {
    b: {
      c: undefined
    }
  },
  b: {
    c: 15,
    d: []
  },
  c: {
    d: [11, undefined ,12],
    e: {}
  }
};

console.log(removeRecursive(obj));


推荐阅读