从Javascript中的Object中删除空白属性

时间:2008-11-13 03:02:13

标签: javascript

如何删除JavaScript对象中undefinednull的所有属性?

(问题类似于数组的this one

40 个答案:

答案 0 :(得分:304)

使用一些 ES6 / ES2015

1)一个简单的单行程序,用于删除内联项而不分配:

Object.keys(myObj).forEach((key) => (myObj[key] == null) && delete myObj[key]);

jsbin

2)此示例已删除...

3)作为函数编写的第一个示例:

const removeEmpty = (obj) => {
  Object.keys(obj).forEach((key) => (obj[key] == null) && delete obj[key]);
}

jsbin

4)此函数使用递归来删除嵌套对象中的项目:

const removeEmpty = (obj) => {
  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === 'object') removeEmpty(obj[key]);
    else if (obj[key] == null) delete obj[key];
  });
};

jsbin

4b)这类似于4),但不是直接改变源对象,而是返回一个新对象。

const removeEmpty = (obj) => {
  const o = JSON.parse(JSON.stringify(obj)); // Clone source oect.

  Object.keys(o).forEach(key => {
    if (o[key] && typeof o[key] === 'object')
      o[key] = removeEmpty(o[key]);  // Recurse.
    else if (o[key] === undefined || o[key] === null)
      delete o[key]; // Delete undefined and null.
    else
      o[key] = o[key];  // Copy value.
  });

  return o; // Return new object.
};

5)基于使用filter()reduce()的{​​{3}}的功能性方法。这个也返回一个新对象:

const removeEmpty = (obj) =>
  Object.keys(obj)
    .filter(k => obj[k] !== null && obj[k] !== undefined)  // Remove undef. and null.
    .reduce((newObj, k) =>
      typeof obj[k] === 'object' ?
        Object.assign(newObj, {[k]: removeEmpty(obj[k])}) :  // Recurse.
        Object.assign(newObj, {[k]: obj[k]}),  // Copy value.
      {});

@MichaelJ.Zoidl's answer

6)与4)相同,但 ES7 / 2016 jsbin

const removeEmpty = (obj) => 
  Object.entries(obj).forEach(([key, val]) => {
    if (val && typeof val === 'object') removeEmpty(val)
    else if (val == null) delete obj[key]
})

7)与4)相同,但在简单的 ES5

function removeEmpty(obj) {
  Object.keys(obj).forEach(function(key) {
    if (obj[key] && typeof obj[key] === 'object') removeEmpty(obj[key])
    else if (obj[key] == null) delete obj[key]
  });
};

Object.entries()

答案 1 :(得分:130)

您可以遍历对象:

var test = {
    test1 : null,
    test2 : 'somestring',
    test3 : 3,
}

function clean(obj) {
  for (var propName in obj) { 
    if (obj[propName] === null || obj[propName] === undefined) {
      delete obj[propName];
    }
  }
}

clean(test);

如果您担心此属性删除没有运行对象的proptype链,您还可以:

function clean(obj) {
  var propNames = Object.getOwnPropertyNames(obj);
  for (var i = 0; i < propNames.length; i++) {
    var propName = propNames[i];
    if (obj[propName] === null || obj[propName] === undefined) {
      delete obj[propName];
    }
  }
}

关于null vs undefined的一些注释:

test.test1 === null; // true
test.test1 == null; // true

test.notaprop === null; // false
test.notaprop == null; // true

test.notaprop === undefined; // true
test.notaprop == undefined; // true

答案 2 :(得分:74)

如果您使用的是lodash或underscore.js,这是一个简单的解决方案:

var obj = {name: 'John', age: null};

var compacted = _.pickBy(obj);

这只适用于lodash 4,pre lodash 4或underscore.js,使用_.pick(obj, _.identity);

答案 3 :(得分:34)

如果有人需要Owen's(和Eric's)答案的递归版本,那么它就是:

/**
 * Delete all null (or undefined) properties from an object.
 * Set 'recurse' to true if you also want to delete properties in nested objects.
 */
function delete_null_properties(test, recurse) {
    for (var i in test) {
        if (test[i] === null) {
            delete test[i];
        } else if (recurse && typeof test[i] === 'object') {
            delete_null_properties(test[i], recurse);
        }
    }
}

答案 4 :(得分:33)

用于ES6 +的最短衬板

过滤所有伪造的值(“”,0,false,null,undefined)

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

过滤null和未定义的值:

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

仅过滤null

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

仅过滤器未定义

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

递归:过滤空值和未定义

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}), {});

答案 5 :(得分:15)

JSON.stringify删除未定义的键。

removeUndefined = function(json){
  return JSON.parse(JSON.stringify(json))
}

答案 6 :(得分:13)

您可能正在寻找delete关键字。

var obj = { };
obj.theProperty = 1;
delete obj.theProperty;

答案 7 :(得分:7)

您可以使用JSON.stringify,其替换参数和JSON.parse的组合将其重新转换为对象。使用此方法还意味着替换嵌套对象中的所有嵌套键。

示例对象

var exampleObject = {
  string: 'value',
  emptyString: '',
  integer: 0,
  nullValue: null,
  array: [1, 2, 3],
  object: {
    string: 'value',
    emptyString: '',
    integer: 0,
    nullValue: null,
    array: [1, 2, 3]
  },
  arrayOfObjects: [
    {
      string: 'value',
      emptyString: '',
      integer: 0,
      nullValue: null,
      array: [1, 2, 3]
    },
    {
      string: 'value',
      emptyString: '',
      integer: 0,
      nullValue: null,
      array: [1, 2, 3]
    }
  ]
};

替换功能

function replaceUndefinedOrNull(key, value) {
  if (value === null || value === undefined) {
    return undefined;
  }

  return value;
}

清理对象

exampleObject = JSON.stringify(exampleObject, replaceUndefinedOrNull);
exampleObject = JSON.parse(exampleObject);

CodePen example

答案 8 :(得分:6)

最简单的Lodash解决方案,用于返回已过滤掉nullundefined值的对象。

_.omitBy(obj, _.isNil)

答案 9 :(得分:5)

使用ramda#pickBy,您将删除所有nullundefinedfalse值:

const obj = {a:1, b: undefined, c: null, d: 1}
R.pickBy(R.identity, obj)

正如@manroe指出的那样,要保持false值使用isNil()

const obj = {a:1, b: undefined, c: null, d: 1, e: false}
R.pickBy(v => !R.isNil(v), obj)

答案 10 :(得分:5)

更短的ES6纯解决方案,将其转换为数组,使用过滤器功能并将其转换回对象。 也很容易做出一个功能...

顺便说一下。使用此.length > 0我检查是否有空字符串/数组,因此它将删除空键。

const MY_OBJECT = { f: 'te', a: [] }

Object.keys(MY_OBJECT)
 .filter(f => !!MY_OBJECT[f] && MY_OBJECT[f].length > 0)
 .reduce((r, i) => { r[i] = MY_OBJECT[i]; return r; }, {});

JS BIN https://jsbin.com/kugoyinora/edit?js,console

答案 11 :(得分:4)

我的项目中有相同的场景,并使用以下方法实现。

它适用于所有数据类型,上面提到的少数数据不适用于日期和空数组。

<强> removeEmptyKeysFromObject.js

removeEmptyKeysFromObject(obj) {
   Object.keys(obj).forEach(key => {
  if (Object.prototype.toString.call(obj[key]) === '[object Date]' && (obj[key].toString().length === 0 || obj[key].toString() === 'Invalid Date')) {
    delete obj[key];
  } else if (obj[key] && typeof obj[key] === 'object') {
    this.removeEmptyKeysFromObject(obj[key]);
  } else if (obj[key] == null || obj[key] === '') {
    delete obj[key];
  }

  if (obj[key]
    && typeof obj[key] === 'object'
    && Object.keys(obj[key]).length === 0
    && Object.prototype.toString.call(obj[key]) !== '[object Date]') {
    delete obj[key];
  }
});
  return obj;
}

将任何对象传递给此函数removeEmptyKeysFromObject()

答案 12 :(得分:4)

如果你想要4行纯ES7解决方案:

const clean = e => e instanceof Object ? Object.entries(e).reduce((o, [k, v]) => {
  if (typeof v === 'boolean' || v) o[k] = clean(v);
  return o;
}, e instanceof Array ? [] : {}) : e;

或者如果您更喜欢更易阅读的版本:

function filterEmpty(obj, [key, val]) {
  if (typeof val === 'boolean' || val) {
    obj[key] = clean(val)
  };

  return obj;
}

function clean(entry) {
  if (entry instanceof Object) {
    const type = entry instanceof Array ? [] : {};
    const entries = Object.entries(entry);

    return entries.reduce(filterEmpty, type);
  }

  return entry;
}

这将保留布尔值,它也将清理数组。它还通过返回已清理的副本来保留原始对象。

答案 13 :(得分:3)

删除所有带有 null 和 undefined 的属性

let obj = {
"id": 1,
"firstName": null,
"lastName": null,
"address": undefined,
"role": "customer",
"photo": "fb79fd5d-06c9-4097-8fdc-6cebf73fab26/fc8efe82-2af4-4c81-bde7-8d2f9dd7994a.jpg",
"location": null,
"idNumber": null,
};

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

答案 14 :(得分:3)

reduce助手可以解决问题(无需类型检查)-

const cleanObj = Object.entries(objToClean).reduce((acc, [key, value]) => {
      if (value) {
        acc[key] = value;
      }
      return acc;
    }, {});

答案 15 :(得分:3)

对于深度搜索,我使用了以下代码,可能对于任何查看此问题的人都有用(它不适用于循环依赖):

function removeEmptyValues(obj) {
        for (var propName in obj) {
            if (!obj[propName] || obj[propName].length === 0) {
                delete obj[propName];
            } else if (typeof obj[propName] === 'object') {
                removeEmptyValues(obj[propName]);
            }
        }
        return obj;
    }

答案 16 :(得分:3)

要在Ben's answer上使用lodash的_.pickBy来解决这个问题,你也可以在姐妹库中解决这个问题:Underscore.js_.pick。< / p>

var obj = {name: 'John', age: null};

var compacted = _.pick(obj, function(value) {
  return value !== null && value !== undefined;
});

请参阅:JSFiddle Example

答案 17 :(得分:2)

如果您不想在适当的位置进行变异,但返回删除了null / undefined的克隆,则可以使用ES6 reduce函数。

// Helper to remove undefined or null properties from an object
function removeEmpty(obj) {
  // Protect against null/undefined object passed in
  return Object.keys(obj || {}).reduce((x, k) => {
    // Check for null or undefined
    if (obj[k] != null) {
      x[k] = obj[k];
    }
    return x;
  }, {});
}

答案 18 :(得分:2)

您可以使用!条件

缩短时间
var r = {a: null, b: undefined, c:1};
for(var k in r)
   if(!r[k]) delete r[k];

请记住使用情况:@semicolor在评论中宣布:如果值为空字符串,则还会删除属性,false或为零

答案 19 :(得分:2)

如果有人需要使用undefined通过深度搜索从对象中删除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;
  }, {});
}

答案 20 :(得分:2)

您也可以使用非空的键创建一个新对象,而不是删除该属性。

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

答案 21 :(得分:1)

这是一种使用ES6从对象中删除nulls而不用仅使用reduce进行对象变异的功能方法:

const stripNulls = (obj) => {
  return Object.keys(obj).reduce((acc, current) => {
    if (obj[current] !== null) {
      return { ...acc, [current]: obj[current] }
    }
    return acc
  }, {})
}

答案 22 :(得分:1)

这是另一种选择

打字稿:

function objectDefined <T>(obj: T): T {
  const acc: Partial<T> = {};
  for (const key in obj) {
    if (obj[key] !== undefined) acc[key] = obj[key];
  }
  return acc as T;
}

JavaScript:

function objectDefined(obj) {
  const acc = {};
  for (const key in obj) {
    if (obj[key] !== undefined) acc[key] = obj[key];
  }
  return acc;
}

答案 23 :(得分:1)

这个问题已经得到了彻底的回答,我只想根据给出的其他示例贡献我的版本:

function filterObject(obj, filter) {
    return Object.entries(obj)
        .map(([key, value]) => {
            return [key, value && typeof value === 'object'
                ? filterObject(value, filter)
                : value];
        })
        .reduce((acc, [key, value]) => {
            if (!filter.includes(value)) {
                acc[key] = value;
            }

            return acc;
        }, {});
}

此解决方案与众不同之处在于可以在第二个参数中指定要过滤的值,如下所示:

const filtered = filterObject(originalObject, [null, '']);

将返回不包含值为null''的属性的新对象(不对原始对象进行突变)。

答案 24 :(得分:1)

这是一个全面的递归函数(最初基于@chickens的递归函数),它将:

  • 递归删除您告诉defaults=[undefined, null, '', NaN]的内容
  • 正确处理常规对象,数组和Date对象
const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
  if (!defaults.length) return obj
  if (defaults.includes(obj)) return

  if (Array.isArray(obj))
    return obj
      .map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
      .filter(v => !defaults.includes(v))

  return Object.entries(obj).length 
    ? Object.entries(obj)
        .map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
        .reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {}) 
    : obj
}

用法:

// based off the recursive cleanEmpty function by @chickens. 
// This one can also handle Date objects correctly 
// and has a defaults list for values you want stripped.

const cleanEmpty = function(obj, defaults = [undefined, null, NaN, '']) {
  if (!defaults.length) return obj
  if (defaults.includes(obj)) return

  if (Array.isArray(obj))
    return obj
      .map(v => v && typeof v === 'object' ? cleanEmpty(v, defaults) : v)
      .filter(v => !defaults.includes(v))

  return Object.entries(obj).length 
    ? Object.entries(obj)
        .map(([k, v]) => ([k, v && typeof v === 'object' ? cleanEmpty(v, defaults) : v]))
        .reduce((a, [k, v]) => (defaults.includes(v) ? a : { ...a, [k]: v}), {}) 
    : obj
}


// testing

console.log('testing: undefined \n', cleanEmpty(undefined))
console.log('testing: null \n',cleanEmpty(null))
console.log('testing: NaN \n',cleanEmpty(NaN))
console.log('testing: empty string \n',cleanEmpty(''))
console.log('testing: empty array \n',cleanEmpty([]))
console.log('testing: date object \n',cleanEmpty(new Date(1589339052 * 1000)))
console.log('testing: nested empty arr \n',cleanEmpty({ 1: { 2 :null, 3: [] }}))
console.log('testing: comprehensive obj \n', cleanEmpty({
  a: 5,
  b: 0,
  c: undefined,
  d: {
    e: null,
    f: [{
      a: undefined,
      b: new Date(),
      c: ''
    }]
  },
  g: NaN,
  h: null
}))
console.log('testing: different defaults \n', cleanEmpty({
  a: 5,
  b: 0,
  c: undefined,
  d: {
    e: null,
    f: [{
      a: undefined,
      b: '',
      c: new Date()
    }]
  },
  g: [0, 1, 2, 3, 4],
  h: '',
}, [undefined, null]))

答案 25 :(得分:1)

如果您使用eslint并希望避免使用无参数重新分配规则,可以将Object.assign与.reduce结合使用,并将计算属性名称用于相当优雅的ES6解决方案:

const queryParams = { a: 'a', b: 'b', c: 'c', d: undefined, e: null, f: '', g: 0 };
const cleanParams = Object.keys(queryParams) 
  .filter(key => queryParams[key] != null)
  .reduce((acc, key) => Object.assign(acc, { [key]: queryParams[key] }), {});
// { a: 'a', b: 'b', c: 'c', f: '', g: 0 }

答案 26 :(得分:1)

您还可以使用...的{​​{1}}扩展语法,如下所示:

forEach

答案 27 :(得分:1)

使用抽象函数的纯函数方法

通常,我们希望获得一个不包含某些值的新对象。 Usign ES7:

const getObjWithoutVals = (dontReturnValsArr, obj) => (
    Object.entries(obj).reduce(
        (newObj, [key, val]) => {
            if(!dontReturnValsArr.includes(val)) newObj[key]= val 
            return newObj
        }
        , {}
    )
)

私人大小写-删除空白值

首先让我们管理我们的功能,以便在这种情况下使用它。

const curriedGetObjWithout = R.curry(getObjWithoutVals)

现在让我们创建一个排除空值的新函数

const getObjWithoutEmpty = curriedGetObjWithout(["", null, undefined])

答案 28 :(得分:0)

您可以使用json.stringify's replacer argument

在一行中进行递归删除
const removeNullValues = obj => (
  JSON.parse(JSON.stringify(obj, (k,v) => v==null?undefined:v))
)

用法:

removeNullValues({a:{x:1,y:null,z:undefined}}) // Returns {a:{x:1}}

答案 29 :(得分:0)

以递归方式删除null,未定义,空对象和空数组,并返回副本(ES6版本)

export function skipEmpties(dirty) {
    let item;
    if (Array.isArray(dirty)) {
        item = dirty.map(x => skipEmpties(x)).filter(value => value !== undefined);
        return item.length ? item : undefined;
    } else if (dirty && typeof dirty === 'object') {
        item = {};
        Object.keys(dirty).forEach(key => {
            const value = skipEmpties(dirty[key]);
            if (value !== undefined) {
                item[key] = value;
            }
        });
        return Object.keys(item).length ? item : undefined;
    } else {
        return dirty === null ? undefined : dirty;
    }
}

答案 30 :(得分:0)

功能和不变的方法,没有.filter,并且没有创建超出需要的对象

Object.keys(obj).reduce((acc, key) => (obj[key] === undefined ? acc : {...acc, [key]: obj[key]}), {})

答案 31 :(得分:0)

我们可以使用JSON.stringify和JSON.parse从对象中删除空白属性。

PATCH https://dev.azure.com/{project}/_apis/wit/workitems/{id}?api-version=5.0

答案 32 :(得分:0)

如果您不想修改原始对象(使用某些ES6运算符):

const keys = Object.keys(objectWithNulls).filter(key => objectWithNulls[key]);
const pairs = keys.map(key => ({ [key]: objectWithNulls[key] }));

const objectWithoutNulls = pairs.reduce((val, acc) => ({ ...val, ...acc }));

filter(key => objectWithNulls[key])返回真实的所有内容,因此将拒绝诸如0false以及undefinednull。如果这是不必要的行为,可以轻松更改为filter(key => objectWithNulls[key] !== undefined)或类似的内容。

答案 33 :(得分:0)

如果您只想从对象中删除未定义的顶级属性,我认为这是最简单的:

const someObject = {
  a: null,
  b: 'someString',
  c: 3,
  d: undefined
};

for (let [key, value] of Object.entries(someObject)) {
  if (value === null || value === undefined) delete someObject[key];
}

console.log('Sanitized', someObject);

答案 34 :(得分:0)

ES6 arrow function and ternary operator:
Object.entries(obj).reduce((acc, entry) => {
   const [key, value] = entry
  if (value !== undefined) acc[key] = value;
  return acc;
}, {})
    const obj = {test:undefined, test1:1 ,test12:0, test123:false};
    const newObj = Object.entries(obj).reduce((acc, entry) => {
       const [key, value] = entry
      if (value !== undefined) acc[key] = value;
      return acc;
    }, {})
    console.log(newObj)

答案 35 :(得分:0)

如果您喜欢纯粹/实用的方法

const stripUndef = obj => 
  Object.keys(obj)
   .reduce((p, c) => ({ ...p, ...(x[c] === undefined ? { } : { [c]: x[c] })}), {});

答案 36 :(得分:0)

删除空字段对象

for (const objectKey of Object.keys(data)) {
      if (data[objectKey] === null || data[objectKey] === '' || data[objectKey] === 'null' || data[objectKey] === undefined) {
        delete data[objectKey];
      }
    }

答案 37 :(得分:0)

Lodash:

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

答案 38 :(得分:0)

如果可以使用Lodash,可以添加DeepDash递归库,并通过一些简洁的代码来实现所需的功能:

const prune = obj => _.filterDeep(obj, (v) => !(_.isUndefined(v) || _.isNull(v)));

调用prune(anObjectWithNulls)将返回没有undefinednull值的对象。

答案 39 :(得分:-1)

30多个答案,但是我没有看到这个简短的ES6线性代码,因为Object.assign()是一个无变量忽略任何非对象(如false)的vararg函数,所以使用了散布运算符。

Object.assign({}, ...Object.entries(obj).map(([k,v]) => v != null && {[k]: v]))