如何过滤掉数组中的 NaN, null, 0, false (JS)

How to filter() out NaN, null, 0, false in an array (JS)

我被要求在 array.

中过滤掉 NaN, null, 0, false

幸运的是我已经回答了这个问题。

function bouncer(arr) {
  function filterer(arr) {
     return arr > 0|| isNaN(arr) === true;
  }
  arr = arr.filter(filterer);
  return arr;
}

//example input
bouncer([0, 1, 2, 3, 'ate', '', false]); //output [1, 2, 3, 'ate']

但问题是我真的不知道我是怎么想出答案的,或者更确切地说,我不知道它是如何工作的。特别是 arr > 0 过滤器如何知道 arr 已在 arr[1]、arr[2] 等上读取,而不使用循环遍历所有数组。

或者可以简单地解释一下代码是如何工作的。 [我已经尽力解释清楚了---]

查看docs Array.filter。请特别注意回调的参数:

Function to test each element of the array. Invoked with arguments (element, index, array). Return true to keep the element, false otherwise.

所以在你的情况下 arr 是元素(而且命名不当,因此你的困惑)。过滤器循环遍历您的数组,对于它调用您的每个项目,回调将当前位置的元素作为 arr 传入。

正如其他人在评论中指出的那样,您的过滤器回调逻辑实际上存在负值缺陷,但如果您知道您的数组永远不会包含负值(但这可能是假设是一件危险的事情。

当然,在内部,这是循环遍历您的数组。如果不触及数组中的每个元素,就无法过滤(未排序的)数组。查看 link 中的 polyfil,了解它 可能如何 工作(可能是因为这是一个实现细节,可能因不同的 javascript 引擎而异,但毫无疑问会在某处涉及一个循环),它循环遍历您的数组,调用回调(注意参数),如果回调 returns 为真,它将被推送到结果数组。

Function to test each element of the array. Invoked with arguments (element, index, array). Return true to keep the element, false otherwise

如果你只是想要解释。顾名思义,数组 filter()。如果条件出错,则删除不需要的元素 (false)。

(arr > 0|| isNaN(arr) === true)

0,  false || false  //removed
1,  true || false  
2,  true || false
3,  true || false
'ate', false || true
'',   false|| false  // removed
false  false || false //removed

输出:

[1, 2, 3, "ate"]

如果要求您过滤掉数组中的 NaNnull0false,那么您的解决方案实际上并不奏效。

您的输入:

bouncer([0, 1, 2, 3, 'ate', '', false, NaN]);

将得到输出:

[1, 2, 3, 'ate', NaN]

要过滤掉所有 'falsy' 值,您只需使用 Boolean:

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

bouncer([0, 1, 2, 3, 'ate', '', false, NaN]);

输出:

[1, 2, 3, 'ate']

由于 Boolean 构造函数也是一个函数,它 returns 要么 true 用于“真实”参数,要么 false 用于“虚假”参数。如果该值被省略或为 0-0nullfalseNaNundefined 或空字符串 (""), 该对象的值为 false。所有其他值,包括任何对象或字符串 "false",创建一个初始值为 true.

的对象

假设所有不需要的元素在布尔值预期时都被转换为 false 的假设不会更优雅,所以:

function clear (arr){
   var stripped = [];
   for (i = 0, len = arr.length; i < len; i++){
      if (arr[i])
         stripped.push(arr[i]);
   }
   return stripped;
}

我也在研究 Free Code Camp Falsy Bouncer 算法。我发现最简单的方法是:

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

您也可以使用恒等函数代替 Boolean

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

The filter() method creates a new array with all elements that pass the test implemented by the provided function.

因为 falsenull0""undefinedNaN 都是 Falsy 中的值 JavaScript 因此在测试时它们将 return false

function bouncer(arr) {
  var array = arr.filter(function(val){
    return val;
  });
  return array;
}

只有 不 return false 的值才会添加到 数组

因为我是编码初学者,所以我的逻辑是使用原始布尔值来比较项目的 过滤,但这是在我阅读布尔对象参考之前,你看到的是 就像它写在那里, "The value passed as the first parameter is converted to a Boolean value if necessary. If value is omitted or is 0, -0, null, false, NaN, undefined, or the empty string (""),对象的初始值为 false。所有其他值,包括任何对象或字符串 "false",都会创建一个初始值为 true 的对象。” 所以逻辑自过滤器 returns 值,如果它是真或假,你应该 return 值如果 他们是真的。 另外,我没有学习有关过滤方法的所有知识,对于我所研究的内容,我有 更多信息,我将在此处尝试解释。´

重新定义方法(已经存在,仅供理解) filter 方法接受一个名为 谓词,即接收的函数 一个值和 returns true 或 false。

var results 是一个空数组,结果将使用 push 方法推送到其中。 我们对此使用 forEach 方法,(在此上下文中,此方法应用于数组原型,这意味着您将在您定义的每个数组上使用过滤器方法, 在这种情况下 array.method(args) 的语法 array.filter(args)) 一些资源 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype

现在我们将 运行 使用 forEach 方法对数组中的每个项目进行操作,现在我们将谓词函数应用于数组的项目,如果它 returns是的,会将其添加到结果中。

Array.prototype.filter = function(predicate){   
    var results = [];

    this.forEach(function(item) {   
        if (predicate(item)) {
            results.push(item);
        }

    });
};

//----------------------------正解---------- ------------------

function bouncer (arrToFilter){

    return arrToFilter.filter(Boolean);
}

//------------没有过滤方法的代码--------

function bouncerNoFilterMethod(arrToFilter){
    var results = [];

    arrToFilter.forEach(function(arrToFilter){
        if(arrToFilter){
            results.push(arrToFilter);
        }
    });

    return  results;    
}

console.log(bouncerNoFilterMethod([7, "ate", "", false, 9]));
console.log(bouncerNoFilterMethod(["a", "b", "c"]));
console.log(bouncerNoFilterMethod([false, null, 0, NaN, undefined, ""]));
console.log(bouncerNoFilterMethod([1, null, NaN, 2, undefined]));
console.log(bouncer([7, "ate", "", false, 9]));
console.log(bouncer(["a", "b", "c"]));
console.log(bouncer([false, null, 0, NaN, undefined, ""]));
console.log(bouncer([1, null, NaN, 2, undefined]));

希望这有助于理解,方法,首先不理解的是传递函数的部分,方法的谓词,如果我在这里有错误,请提出更正。

对于 "FreeCodeCamp" 挑战,布尔值看起来是最简单的 fix/answer,但是尝试一些事情可能对掌握 "why" 和 "how".

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

这会使用传入的函数(回调)评估通过过滤器的所有内容,returns 值。如果它不是 return 值(null 等不会),它将不会包含在 return 中。至少这种方法帮助我理解了为什么而不是仅仅通过测试。

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

  function isFalsyBouncer(value){
    if(Boolean(false)||Boolean(null)||Boolean(0)||Boolean("")||Boolean(undefined)||Boolean(NaN)){

    }else{
      return value;
    }
  }
  var filtered=arr.filter(isFalsyBouncer);
  return filtered;
}

我稍微修改了,将没有数值的所有内容都设置为零

function zerofy(x){return (Boolean(x) && !isNaN(x.toString())) ? x : 0 ;}

测试

function clear (arr){
   var stripped = [];
   for (i = 0; i < arr.length; i++){
      stripped.push(zerofy(arr[i]));
   }
   return stripped;
}

clear(["written",13,0,-4,"5",true,false,undefined,null,NaN,Math.PI]);

结果

[0,13,0,-4,5,0,0,0,0,0,3.141592653589793]