如何在JS中从数组中删除空对象

49

我有一个对象数组,当我将其转换成字符串时,它看起来像这样:

"[[{"entrReqInv": "Neither"},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}]]"

我该如何删除空的{}


@jfriend00 我编辑了问题以反映正确的JS对象语法。 - Alacritas
9个回答

102
var newArray = array.filter(value => Object.keys(value).length !== 0);

我同意,但你应该加上提示,并添加一个ES5的例子,因为它可能不适用于所有情况。 - webdeb
我的答案是ES5版本。 - Barmar
11
array.filter((item) => Object.keys(item).length);这句话的意思是:筛选数组中那些对象属性不为空的元素。其中,array表示要操作的数组,filter()方法返回一个新的数组,包含满足条件的元素。在括号内的箭头函数((item) => Object.keys(item).length)是指筛选出那些具有非空属性的元素。简单解释一下箭头函数的意思:(item)表示当前处理的元素,在这里是一个对象;Object.keys(item)获取该对象所有属性名组成的数组;.length表示该数组的长度,即该对象属性的数量。如果该值为0,则认为该对象属性为空,该元素被过滤掉;否则保留该元素。整句话的翻译如下:筛选数组中那些对象属性不为空的元素。 - Sinux
1
@Sinux的回答很好,但请记住,在数组上调用filter()不会改变原始数组,因此您需要重新分配它,例如:array = array.filter((item) => Object.keys(item).length); - Sublow
2
如果数组包含未定义的对象,那么这将不起作用。即 [{name:"abc"}, undefined]。 - Ch Usman

13
您可以使用 Array.prototype.filter 在字符串化之前删除空对象。
JSON.stringify(array.filter(function(el) {
    // keep element if it's not an object, or if it's a non-empty object
    return typeof el != "object" || Array.isArray(el) || Object.keys(el).length > 0;
});

这也将过滤掉空数组。 - Roamer-1888
@Roamer-1888 有没有办法区分数组和其他对象?不管怎样,他说他有一个对象数组,所以可能无关紧要。 - Barmar
实际上,我们不知道它是否重要。如果是的话,请将 Array.isArray(el) 添加到过滤器中。 - Roamer-1888
不算真正的向后兼容,但仍然是一种解决方案。 - StackSlave
谢谢大家!!!终于对我有用了!!!我应该真的上传一张照片……它是女孩 :) 感谢帮助。 - Rudy

12

我建议使用以下代码:

var newArray = array.filter(value => JSON.stringify(value) !== '{}');

我没有使用 Object.keys(value).length !== 0,因为它不仅会移除空对象 { },还会移除空数组 [ ]。如果你只想要移除空对象,使用上述方法即可。


4
如果您的对象数组是这样的 -
finalobj--- [ { 'patient._id': '123' },
  { 'patient.birthDate': 'lt2013-01-14', {}, {} } ]

然后使用以下代码删除空对象 --
var newArray = obj.filter((value: {}) => Object.keys(value).length !== 0);

1
更简单易懂的理解方式:
let primaryArray = [{key:'value'},{},{},{}]
let removeObsoletesArray = []
primaryArray.forEach( element => {
   if(element.length > 0){
      removeObsoletesArray.push(element)
   }
})

如果你这样做:Object.keys(dictionary).length,它就能正常工作。 - AbuZubair

0
const arrValues = [{
  x: 100
}, {
  x: 200
}, {}];
let filteredArra = arrValues.filter(
  obj => !(obj && Object.keys(obj).length === 0)
);

0

出于渐进增强的原因,这是我会做的:

var aryAry = [[{prop: 'value'},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}]];
var a = aryAry[0], r = [];
for(var i=0,l=a.length; i<l; i++){
  var n = 0, o = a[i];
  for(var q in o){
    n++;
  }
  if(n > 0){
    r.push(o);
  }
}
console.log(r);

你对 splice() 的参数有误,应该是 (i, 1)。但这也会跳过被删除的元素之后的那个元素,因为那个元素将变成 i - Barmar
1
他是否想修改数组本身还不清楚,只是在序列化时不包括空元素。 - Barmar
那个内部循环是一种相当冗长的方法来执行 n = Object.keys(o).length; - Barmar
我早就不再担心IE8了。如果它需要一个polyfill,它可以自己查找。 - Barmar
根据此链接,今年您缺失了超过14%的市场份额。 - StackSlave

0
如果你想让这段代码更易读,我建议和 lodash 结合使用:
var filteredArray = array.filter(value => !_.isEmpty(value));

这应该过滤空对象和未定义的内容。


-3

let arr = [{a:1},{},{c:3}];

arr = _.filter(arr,v => _.keys(v).length !== 0);

console.log(arr)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

arr = _.filter(arr, v => _.keys(v).length !== 0);

arr = _.filter( arr,v => _.keys(v).length!== 0);


你可能还需要对答案进行解释。 - Romil Patel
1
你好,欢迎来到Stack Overflow。当回答一个已经有几个答案的问题时,请确保添加一些额外的见解,说明你提供的回答是实质性的,而不仅仅是重复原始发布者已经审核过的内容。这在“仅代码”答案中尤为重要,比如你提供的那个答案。 - chb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接