从数组中删除未定义的值

139
在某些情况下,数组结构中可能存在 undefined 或一般性的“falsy”值。例如,在从某些未知来源(如数据库或HTML结构)读取和填充数据时。
var data = [42, 21, undefined, 50, 40, undefined, 9]

因为这可能会在循环这样的数组并处理元素时造成麻烦,所以删除undefined(假值)的最佳实践是什么?


1
这个怎么样?http://jsfiddle.net/5uuyoo5t/ - Rakesh_Kumar
15个回答

230

在这里使用Array.prototype.filter可能是很明显的。所以要只删除未定义的值,我们可以调用

使用Array.prototype.filter在这里可能很明显。因此,为了仅删除未定义的值,我们可以调用

var data = [42, 21, undefined, 50, 40, undefined, 9];

data = data.filter(function( element ) {
   return element !== undefined;
});
如果我们想要过滤掉所有的假值(如0或null),我们可以使用return !!element;。但我们可以更加优雅地实现它,只需将Boolean构造函数或者Number构造函数传递给.filter函数:
data = data.filter( Number );

在这种情况下,那就可以胜任了,如果要通常删除任何falsy值,我们会调用

data = data.filter( Boolean );

由于Boolean()构造函数对于真值返回true,对于任何假值返回false,因此这是一个非常简洁的选项。


20
请注意,filter(Number) 也会删除数字 0 - Lewis
6
这也将删除类似于false这样的假值,它们可能存在于数组中。 - lfender6445
@jAndy 谢谢。这也解决了我在IE 11中的问题。之前我使用箭头函数来删除未定义的内容。 - sgajera
2
这可以缩短为.filter(n=>n!==undefined) - ctwheels
2
有些人可能会感到困惑,因此:回调函数接收元素,这意味着执行 filter(Boolean) 与执行 filter((elem)=>Boolean(elem)) 是相同的。 - trogne
显示剩余2条评论

136

使用lambda表达式进行内联

result.filter(item => item);

14
这个答案将会移除所有“假值”。由于提问者明确表示不需要“假值”,所以在我看来这绝对是最好的答案。然而,他们还特别指出了未定义的情况,在这种情况下,你需要使用result.filter(item => item !== undefined) - Braden Rockwell Napier
4
[true,false,undefined,null,'a',1,0,'0'].filter(x=>x) 的返回值为 [true, "a", 1, "0"]。原数组中的 falseundefinednull0 均被过滤掉了,只剩下了真值 true、字符串 "a"、数字 1 以及字符串 "0" - frumbert
1
最佳答案在这里 - Omar
JS新手报道。人们说这是最佳答案,但为什么它比 filter(Boolean)filter(item => !!item) 更好? - Adam Hughes
1
@AdamHughes 并不是这样,人们经常高估简洁性而忽视清晰度。在这三种方式中,filter(item => !!item) 实际上是最好的,因为它清楚地表达了你正在根据 item 的真值进行过滤。Boolean 则是最糟糕的,因为输入和操作都不再明确。而且它看起来像是你正在筛选布尔值,而实际上并不是这样。 - John Neuhaus

32
您可以使用 lodash 库的 compact 方法,该方法会移除 nullundefined''
_.compact(data)

13
那并非自由可得的,需要使用另一个库。这就有些过头了。 - Paul Brunache
2
这个代码可运行并清空数组。这是我喜欢的解决方案。 - Rigin Oommen

28
[NaN, undefined, null, 0, 1, 2, 2000, Infinity].filter(Boolean)
//[ 1, 2, 2000, Infinity ]

24

如果你有一个对象数组,并且想要移除所有的nullundefined项:

[].filter(item => !!item);

22

ES6 单行语法

data.filter(e => e)

8
注意,这也会移除任何“虚假”值,例如零。[undefined, null, 0, false].filter(e => e) // [] - Jason Moore
1
JavaScript 有时候很奇怪 :D - Rejo Chandran
这对于对象数组来说是最好的选择。 - undefined

19
data.filter(Boolean)

这是完成它的最短和最易读的方式。


4
为什么这个方法有效?不要只写“魔法”,还要解释它是如何起作用的,以及为什么这是一个好的解决方案。 - Lucian Enache
1
@LucianEnache 它对数组的每个项应用布尔函数,如果转换为false,则过滤掉它。在此处阅读更多信息:https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Boolean - Yan Takushevich
为什么结果数组仍然被认为可能包含未定义的内容? - SeanMC
2
@SeanMC 这是另一个关于TypeScript的问题。它与array.filter不兼容。您可以在此主题中找到其他信息:https://dev59.com/RlgQ5IYBdhLWcg3wSh91 - Yan Takushevich
1
最短的说“最短”的方式是“最短”,这也是最易读的方式。 - jox

6
正如Diogo Capela所说,但是0也没有被过滤掉。
[].filter(item => item !== undefined && item !== null)

4
var a =  ["3","", "6"];
var b =  [23,54,56];
var result = [];

for (var i=0;i<a.length;++i) {
    if (a[i] != "") {
        result[i] = b[i];
    }
}

result = result.filter(function( element ) {
   return element !== undefined;
});

console.log(result);

4
var arr1 = [NaN, 0, 15, false, -22, '',undefined, 47, null];

var array1 = arr1.filter(function(e){ return e;});

document.write(array1);

单行回答


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