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

abh*_*jit 208 javascript

如何删除这些都是属性undefinednull在JavaScript对象?

(问题类似于这个阵列)

Rot*_*eti 365

使用一些ES6/ES2015:

1)一个简单的单行内容删除内联项目而不分配:

Object.keys(myObj).forEach((key) => (myObj[key] == null) && delete myObj[key]);
Run Code Online (Sandbox Code Playgroud)

jsbin

2)这个例子被删除了......

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

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

jsbin

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

const removeEmpty = obj => {
  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === "object") removeEmpty(obj[key]); // recurse
    else if (obj[key] == null) delete obj[key]; // delete
  });
};
Run Code Online (Sandbox Code Playgroud)

jsbin

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

const removeEmpty = obj => {
  const newObj = {};

  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === "object") {
      newObj[key] = removeEmpty(obj[key]); // recurse
    } else if (obj[key] != null) {
      newObj[key] = obj[key]; // copy value
    }
  });

  return newObj;
};
Run Code Online (Sandbox Code Playgroud)

5)基于@ MichaelJ.Zoidl的回答使用和的4b)的功能方法.这个也返回一个新对象:filter()reduce()

const removeEmpty = obj =>
  Object.keys(obj)
    .filter(k => obj[k] != null) // Remove undef. and null.
    .reduce(
      (newObj, k) =>
        typeof obj[k] === "object"
          ? { ...newObj, [k]: removeEmpty(obj[k]) } // Recurse.
          : { ...newObj, [k]: obj[k] }, // Copy value.
      {}
    );
Run Code Online (Sandbox Code Playgroud)

jsbin

6)与4)相同,但使用ES7/2016 Object.entries().

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

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

const removeEmpty = obj =>
  Object.fromEntries(
    Object.entries(obj)
      .filter(([k, v]) => v != null)
      .map(([k, v]) => (typeof v === "object" ? [k, removeEmpty(v)] : [k, v]))
  );
Run Code Online (Sandbox Code Playgroud)

jsbin

  • 既然我们正在努力做到彻底,那么看到一个不可变的解决方案可能会很好.这些正在改变源对象并且欺骗性地返回实际上不必要的对象,因为该对象已经变异.初学者将捕获返回的对象值,并想知道为什么他们的源对象也被修改. (6认同)
  • @AugustinRiedinger当我必须在换行符和缩写之间做出决定时,如果我认为缩写是较小的邪恶,我有时会选择缩写.5)中的代码并不难理解,它是一个从"对象"中删除空"键"的函数,因此"o"和"k"是显而易见的.但我想这是一个品味问题. (3认同)
  • 第一个带有ES5风格的版本:`Object.keys(myObj).forEach(function(key){(myObj [key] == null)&& delete myObj [key]});` (3认同)
  • 一行,没有函数:`Object.entries(myObj).reduce((acc, [key, val]) => { if (val) acc[key] = val; return acc; }, {})` (2认同)
  • 5)不适用于数组(Object.keys将返回数组位置编号作为元素的键)。可能其他人有这个问题,但是我在测试5时发现了这个问题。 (2认同)
  • 对于任何对嵌套处理程序代码、修复数组转换为对象的错误以及删除空嵌套对象和数组感兴趣的人,这里有一个更新的代码([在此处测试](https:// jsfiddle.net/c217t6pd/)): `function removeEmpty(obj) { var clean = Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, v === Object( v) ?removeEmpty(v) : v]).filter(([_, v]) => v != null && (v !== Object(v) || Object.keys(v).length))) ; 返回 Array.isArray(obj) ?Object.values(clean) : 干净;}` (2认同)

Owe*_*wen 156

你可以遍历对象:

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);
Run Code Online (Sandbox Code Playgroud)

如果您担心此属性删除没有运行对象的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];
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

关于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
Run Code Online (Sandbox Code Playgroud)

  • 你可以简化(test [i] === null || test [i] === undefined)to(test [i] == null) (4认同)
  • 添加了快速更正.如果此片段曾在函数中使用过,则未声明的"i"变量将泄漏到外部作用域中. (2认同)

Ben*_*Ben 82

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

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

var compacted = _.pickBy(obj);
Run Code Online (Sandbox Code Playgroud)

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

  • 请注意,如果对象包含虚假值(如0或空字符串),则不会产生所需的结果.然后`_.omit(obj,_.isUndefined)`更好. (19认同)
  • @JHH `_.isUndefine` 不省略 null,使用 `_.omitBy(obj, _.isNil)` 省略 `undefined` 和 `null` (8认同)
  • @JHH您的代码不适用于`false`值。 (2认同)

Wum*_*mms 36

如果有人需要Owen(和Eric的)答案的递归版本,这里是:

/**
 * 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


chi*_*ens 22

ES6 +的最短衬管

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

Object.entries(obj).reduce((a,[k,v]) => (v ? {...a, [k]:v} : a), {})
Run Code Online (Sandbox Code Playgroud)

过滤null和undefined值:

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

仅过滤null

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

筛选器未定义

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

递归:过滤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, [k]:v} : a), {});
Run Code Online (Sandbox Code Playgroud)

  • 这应该是唯一的答案!这些片段中的每一个都会生成一个新对象,其中旧对象不会发生突变。这是可取的!注意事项:如果仅使用v == null,则将检查undefined和null。 (4认同)
  • a,[k,v] =&gt; 累加器, 键, 值 (2认同)

小智 17

JSON.stringify删除未定义的键.

removeUndefined = function(json){
  return JSON.parse(JSON.stringify(json))
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这不会删除“null”值。尝试: `let a = { b: 1, c: 0, d: false, e: null, f: undefined, g: [], h: {} }` 然后 `console.log(removeUndefined(a)) `。问题是关于“未定义”和“空”值。 (2认同)

yfe*_*lum 12

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

var obj = { };
obj.theProperty = 1;
delete obj.theProperty;
Run Code Online (Sandbox Code Playgroud)

  • 这就是他上面所做的,这仍然在对象中留下未定义. (4认同)

Sco*_*son 10

您可以使用json.stringify 的 replacer 参数在一行中进行递归删除

const removeEmptyValues = obj => (
  JSON.parse(JSON.stringify(obj, (k,v) => v ?? undefined))
)
Run Code Online (Sandbox Code Playgroud)

用法:

removeEmptyValues({a:{x:1,y:null,z:undefined}}) // Returns {a:{x:1}}
Run Code Online (Sandbox Code Playgroud)

正如 Emmanuel 的评论中提到的,这种技术仅在您的数据结构仅包含可以放入 JSON 格式的数据类型(字符串、数字、列表等)时才有效。

(这个答案已经更新为使用新Nullish合并运算根据浏览器支持的需求可能要使用此功能代替。(k,v) => v!=null ? v : undefined

  • 这会将 Date 对象转换为字符串,将“NaN”转换为“null”,但不会被删除。 (2认同)

小智 9

删除所有 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)
Run Code Online (Sandbox Code Playgroud)


Ale*_*ler 8

您可以使用JSON.stringify其replacer参数的组合,并将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]
    }
  ]
};
Run Code Online (Sandbox Code Playgroud)

替换功能

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

  return value;
}
Run Code Online (Sandbox Code Playgroud)

清理对象

exampleObject = JSON.stringify(exampleObject, replaceUndefinedOrNull);
exampleObject = JSON.parse(exampleObject);
Run Code Online (Sandbox Code Playgroud)

CodePen示例

  • 对于那些使用 typescript 或较新版本的 Node/js 的人来说,这是一个较短的版本。`const clean = (object: object) =&gt; JSON.parse(JSON.stringify(object, (_, value) =&gt; value ?? undefined));` (2认同)

Jef*_*D23 8

Lodash解决方案最简单的解决方案,可返回过滤出nullundefined值的对象。

_.omitBy(obj, _.isNil)


ngu*_*yên 7

你可以做更短的!条件

var r = {a: null, b: undefined, c:1};
for(var k in r)
   if(!r[k]) delete r[k];
Run Code Online (Sandbox Code Playgroud)

使用时请记住:如@semicolor 在评论中宣布:如果值为空字符串、false 或零,这也会删除属性

  • 如果值为空字符串、false 或零,这也会删除属性。 (11认同)
  • 这正是我想要从 JSON 请求中删除不需要的字段的方法。谢谢! (3认同)

bha*_*ppa 6

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

它适用于所有数据类型,上面提到的很少适用于 date 和 empty arrays 。

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;
}
Run Code Online (Sandbox Code Playgroud)

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


per*_*lmq 6

Functional and immutable approach, without .filter and without creating more objects than needed

Object.keys(obj).reduce((acc, key) => (obj[key] === undefined ? acc : {...acc, [key]: obj[key]}), {})
Run Code Online (Sandbox Code Playgroud)


sam*_*sam 5

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

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;
    }
Run Code Online (Sandbox Code Playgroud)


Ami*_*.io 5

使用ramda#pickBy你会删除所有nullundefinedfalse值:

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

正如@manroe所指出的,要保留false值,请使用isNil()

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


小智 5

Instead of delete the property, you can also create a new object with the keys that are not null.

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


Mic*_*idl 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; }, {});
Run Code Online (Sandbox Code Playgroud)

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


Emm*_*N K 5

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

  • 递归地删除你告诉它的内容defaults=[undefined, null, '', NaN]
  • 正确处理常规对象、数组和日期对象
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
}
Run Code Online (Sandbox Code Playgroud)

用法:

// 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]))
Run Code Online (Sandbox Code Playgroud)


Tho*_*ggi 5

这是一个替代方案

打字稿:

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;
}
Run Code Online (Sandbox Code Playgroud)

JavaScript:

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;
}
Run Code Online (Sandbox Code Playgroud)