从数组中删除所有假值

106

我想从数组中删除所有假值。在JavaScript中,假值包括false、null、0、""(空字符串)、undefined和NaN。

function bouncer(arr) {
 arr = arr.filter(function (n) { 
    return (n !== undefined && n !== null && n !== false && n !== 0 && n !== "" && isNaN()!=NaN); });
  return arr;
}

bouncer([7, "ate", "", false, 9, NaN], "");

除了NaN测试用例外,以上所有内容都已满足。请问有人能帮我在数组中检查是否包含NaN吗?

26个回答

230

你可以使用布尔值:

var myFilterArray = myArray.filter(Boolean);

16
那是个聪明的人。 - Farzad Yousefzadeh
16
Boolean是布尔值的构造函数。这等效于var myFilterArray = myArray.filter((v) => new Boolean(v));。如果传入的值为0、-0(我知道…)、null、false、NaN、undefined或空字符串,则结果为false。如果传入其他任何值,则结果为true。 - LoremIpsum
4
如果你尝试这样做,你会发现它永远不会过滤出任何东西,因为 Boolean 作为一个构造函数创建的是布尔包装对象(JavaScript最愚蠢的功能,完全没有任何用处),它们总是为真。相反,使用 Boolean(v) 而不是 new Boolean(v),也就是直接传递 Boolean 所实现的效果,会将其转换为布尔值。 - Ry-
3
这段话的意思是:它等同于var myFilterArray = myArray.filter((v) => Boolean(v));,但是没有使用newnew Boolean会创建真值为truthy的布尔对象,这意味着filter接受所有元素,这与var myFilterArray = myArray.filter(() => true);相当。 - Sebastian Simon
哦,为什么这个在最底下?我刚刚发布了这个问题,因为所有的答案看起来都很棘手。 - Andión
性能如何?这种方法似乎非常慢,因为它需要为每个元素构造Boolean。而且它比.filter(x=>x)更不紧凑。 - Nikola Mihajlović

63

既然你想要摆脱“falsy”值,那就让 JavaScript 处理它:

function bouncer(arr) {
  return arr.filter(function(v) { return !!v; });
}
双重应用 ! 运算符会使过滤回调在值为“真值”时返回true,在值为“假值”时返回false
(您的代码正在调用 isNaN(),但未传递值;这就是为什么该测试对您无效的原因。当强制将其参数转换为数字时,isNaN()函数如果参数为NaN则返回true,否则返回false。) 编辑 - 请注意。
function bouncer(arr) {
  return arr.filter(Boolean);
}

如另一个答案中所述,LoremIpsum指出,!!实际上与内置的布尔构造函数基本相同,因此也可以使用。


很好。函数式方法的技巧不错。 - Farzad Yousefzadeh
9
这个 { return !!v; } 和 { return v; } 是不是一样的? - miatech
5
实际上在这里你甚至不需要使用!!,因为filter测试的是真值而不是与true的比较。 - Steve Bennett

33
truthyArray = arr.filter(el => el)

^那就是你该怎么做


4
花括号会禁用隐式返回,因此你会得到一个空数组。 - vp_arth

20
使用这个简单的过滤器即可: array.filter(Boolean) 你可以在此处阅读更多关于 Boolean 的信息: 这里

2
简单而最佳的解决方案! - rehman_00001

9
您使用了错误的方式来使用isNaN()。应该像以下这样使用:
function bouncer(arr) {
   return arr.filter(function (n) { 
       return n !== undefined && n !== null && n !== false && n !== 0 && n !== "" && !isNaN(n); 
   });

您可以重写它:

同时,您也可以重新编写它:

function bouncer( arr ){
    return arr.filter( function( value ){
        return value;
    });
}

1
上面的代码完美地运行了...你能解释一下在 return arr.filter( function( value ){ return value; }); 中正在发生什么吗? - Vignesh
1
@Vignesh Array.prototype.filter 检查值是否为真,并将其添加到数组中。上面的所有值都不是真值 https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy - ioncreature
在第一种情况下,即使字符串不为空,过滤器也会将其删除,为什么? - Humoyun Ahmad

5
使用过滤器,我们可以编写如下内容:
function bouncer(arr) {
 return arr.filter(item => item);
}
bouncer([false, null, 0, NaN, undefined, ""]) // will return [].

5

以下是另一种等效但具有说明性的解决方案:

function bouncer( arr ){
    return arr.filter( function( value ){
        return value ? true : false;
    });
}

这段代码示例是为了向读者表明变量value将被评估为真值或假值,并且匿名函数将返回布尔值,即truefalse,对应于value的评估。如果对于这种基于真值或假值从数组中删除值的方法不熟悉,或者对于filter函数不熟悉(或未阅读其文档)的人来说,这个例子是最简洁的,同时又能传达filter函数的行为。
当然,在您的应用程序中,您可以选择更简洁但不太深入的实现方式:
function bouncer( arr ){
    return arr.filter( function( value ){
        return value;
    });
}

x ? true : false 总是多余的。只用 return value 就足够了。在某些情况下,您需要使用 Boolean(value)!!value,但不适用于此情况。 - vp_arth
我写下这个答案是为了说明filter函数基于布尔返回值来评估值。如果没有明确表示filter函数对回调的返回值进行布尔型评估,那么仅使用return value;无法充分向新手解释该概念。 - sealocal
拥有这种类型的图示可以使代码更易于阅读。 - cvss

4

我知道可以使用 arr.filter() 方法来实现,但我更喜欢使用 Boolean() 函数,我觉得这样更清晰明了。以下是我的方法,虽然有点长:

function bouncer(arr) {
// Don't show a false ID to this bouncer.

    var falsy;
    var trueArr = [];

    for (i = 0; i < arr.length; i++) {

        falsy =  Boolean(arr[i]);

        if (falsy === true) {

        trueArr.push(arr[i]);

        }

    }

    return trueArr;
}

bouncer([7, "ate", "", false, 9]);
// returns a new array that is filtered accordingly.

3
我认为这样更划算。
   function bouncer(arr) {
        arr = arr.filter(function(item) {
            return item;
        return arr;

    bouncer([7, "ate", "", false, 9, NaN, undefined, 0]);

3
弹道函数:

function bouncer(arr) {
  return arr.filter((val) => {
    return !!val;
  });
}

console.log(bouncer([7, "ate", "", false, 9]));


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