如何删除JavaScript对象中未定义或空的所有属性?

(这个问题与数组的问题类似)


当前回答

除了删除属性,还可以使用非空键创建一个新对象。

const removeEmpty = (obj) => {
  return Object.keys(obj).filter(key => obj[key]).reduce(
    (newObj, key) => {
      newObj[key] = obj[key]
      return newObj
    }, {}
  )
}

其他回答

这可以使用递归来解决。JavaScript对象可以是一个数组,也可以有一个包含空值的数组作为值。

function removeNullValues(obj) {
  // Check weather obj is an array
  if (Array.isArray(obj)) {
    // Creating copy of obj so that index is maintained after splice
    obj.slice(0).forEach((val) => {
      if (val === null) {
        obj.splice(obj.indexOf(val), 1);
      } else if (typeof val === 'object') {
        // Check if array has an object
        removeNullValues(val);
      }
    });
  } else if (typeof obj === 'object') {
    // Check for object
    Object.keys(obj).forEach((key) => {
      if (obj[key] === null) {
        delete obj[key];
      } else if (typeof obj[key] === 'object') {
        removeNullValues(obj[key]);
      }
    });
  }
  return obj;
}

Lodash:

_.omitBy({a: 1, b: null}, (v) => !v)

ES6+的最短一行

过滤所有错误值("",0,false, null, undefined)

Object.entries(obj).reduce((a,[k,v]) => (v ? (a[k]=v, a) : a), {})

过滤空值和未定义值:

Object.entries(obj).reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {})

仅过滤null

Object.entries(obj).reduce((a,[k,v]) => (v === null ? a : (a[k]=v, a)), {})

过滤器仅未定义

Object.entries(obj).reduce((a,[k,v]) => (v === undefined ? a : (a[k]=v, a)), {})

递归解决方案:过滤null和undefined

对象:

const cleanEmpty = obj => Object.entries(obj)
        .map(([k,v])=>[k,v && typeof v === "object" ? cleanEmpty(v) : v])
        .reduce((a,[k,v]) => (v == null ? a : (a[k]=v, a)), {});

对于对象和数组:

const cleanEmpty = obj => {
  if (Array.isArray(obj)) { 
    return obj
        .map(v => (v && typeof v === 'object') ? cleanEmpty(v) : v)
        .filter(v => !(v == null)); 
  } else { 
    return Object.entries(obj)
        .map(([k, v]) => [k, v && typeof v === 'object' ? cleanEmpty(v) : v])
        .reduce((a, [k, v]) => (v == null ? a : (a[k]=v, a)), {});
  } 
}

TypeScript的泛型函数

function cleanProps(object:Record<string, string>):Record<string, string> {
  let cleanObj = {};

  Object.keys(object).forEach((key) => {
    const property = object[key];
    cleanObj = property ? { ...cleanObj, [key]: property } : cleanObj;
  });

  return cleanObj;
}

export default cleanProps;

现在假设你有一个像下面这样的对象

interface Filters{
 searchString: string;
 location: string;
 sector: string
}

const filters:Filters = {
  searchString: 'cute cats',
  location: '',
  sector: 'education',
};

您可以按照如下方式使用该函数

const result = cleanProps(filters as Record<keyof Filters, string>);
console.log(result); // outputs: { searchString: 'cute cats', sector: 'education' }

如果有人需要使用lodash从对象中删除未定义的值,然后这里是我使用的代码。修改它以删除所有空值(null/undefined)非常简单。

function omitUndefinedDeep(obj) {
  return _.reduce(obj, function(result, value, key) {
    if (_.isObject(value)) {
      result[key] = omitUndefinedDeep(value);
    }
    else if (!_.isUndefined(value)) {
      result[key] = value;
    }
    return result;
  }, {});
}