【问题标题】:JavaScript filter arraysJavaScript 过滤器数组
【发布时间】:2016-11-16 11:14:40
【问题描述】:

我正在学习在线 JavaScript 课程,我对其中一项任务感到好奇:

我们提供了一个初始数组(销毁函数中的第一个参数),然后是一个或多个参数。我们必须从初始数组中删除与这些参数具有相同值的所有元素。

这是我的解决方案,但它不起作用:

 function destroyer(arr) {
   // Separating the array from the numbers, that are for filtering; 
   var filterArr = [];
   for (var i = 1; i < arguments.length; i++) {
     filterArr.push(arguments[i]);
   }

   // This is just to check if we got the right numbers
   console.log(filterArr);

   // Setting the parameters for the filter function
   function filterIt(value) {
       for (var j = 0; j < filterArr.length; j++) {
         if (value === filterArr[j]) {
           return false;
         }
       }
     }
     // Let's check what has been done
   return arguments[0].filter(filterIt);
 }

 destroyer([1, 2, 3, 1, 2, 3], 2, 3);

我能够找到解决方案,但这对我来说没有任何意义,这就是我发布这个问题的原因;你能告诉我为什么下面的代码有效吗:

function destroyer(arr) {
  // Separating the array from the numbers, that are for filtering; 
  var filterArr = [];
  for (var i = 1; i < arguments.length; i++) {
    filterArr.push(arguments[i]);
  }

  // This is just to check if we got the right numbers
  console.log(filterArr);

  // Setting the parameters for the filter function
  function filterIt(value) {
      for (var j = 0; j < filterArr.length; j++) {
        if (value === filterArr[j]) {
          return false;
        }
        // This true boolean  is what makes the code to run and I can't                  // understand why. I'll highly appreciate your explanations.
      }
      return true;
    }
    // Let's check what has been done
  return arguments[0].filter(filterIt);
}

destroyer([1, 2, 3, 1, 2, 3], 2, 3);

感谢您的提醒!

【问题讨论】:

  • filter 中的函数需要返回一些值。如果为真(例如true),则保留该元素,如果为假(例如false),则将其删除。您只会返回 falseundefined(自动),这是错误的。
  • 如果要保留元素,传递给filter 方法的函数必须返回true。如果它只返回false,它将删除所有内容。 Not 返回值被视为返回false

标签: javascript arrays


【解决方案1】:

您可以通过使用Array.prototype.reduce() 来使用相对简单的代码来完成相同的工作,如下所示;

ES6

var destroyer = (a,...f) => a.reduce((p,c) => f.includes(c) ? p : p.concat(c),[]);
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));

或在 ES5 中

function destroyer(a){
  var f = Array.prototype.slice.call(arguments,1);
  return a.reduce(function(p,c){
                    return f.indexOf(c) !== -1 ? p : p.concat(c);
                  },[]);
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));

【讨论】:

    【解决方案2】:

    filter 是一个数组原生函数。它创建一个包含所有通过给定测试的元素的新数组。测试函数必须返回一个布尔值,如果true 该值未被过滤掉,如果false 则被过滤掉。

    浏览文档: Filter- Array

    您发布的正确解决方案具有用于过滤给定数组的有效测试函数,该函数针对特定用例返回truefalse(这里是消除作为参数提供的数字的逻辑)。

    您的实现错过了返回 true(它返回 undefined,这是 Javscript 中的一个虚假值,因此所有值都被过滤掉了,你得到一个空数组。

    注意:这里true指的是JS中的所有真值,false指的是JS中的所有假值。

    【讨论】:

      【解决方案3】:

      您的代码不起作用,因为您没有返回 true

      Array.filter 需要一个布尔值作为返回值。如果true,它将添加到结果数据集中。如果false,则会跳过。

      由于您没有返回任何内容,因此默认返回 undefinedundefined 是错误的。因此,您的返回数组将为空白。

      根据MDN

      filter() 为数组中的每个元素调用一次提供的回调函数,并构造一个包含所有值的新数组,回调为其返回强制为 true 的值

      【讨论】:

        【解决方案4】:

        阅读 Rajesh 写的内容,很容易理解 filter() 的工作原理。

        此外,您实际上并不需要辅助函数。 这段代码绰绰有余:
        编辑: Rajesh 建议的代码更少

        function destroyer(arr) {
        
          for (var i = 1, filterArr = []; i < arguments.length; i++) {
            filterArr.push(arguments[i]);
          }
        
          return arguments[0].filter(function(v) {
            return filterArr.indexOf(v)===-1
          });
        }
        
        var result = destroyer([1, 2, 3, 1, 2, 5, 3], 2, 3);
        console.log(result);
        

        【讨论】:

        • 感谢您的信任。您可以将return filterArr.indexOf(v)&gt;-1 替换为您的过滤器回调。
        【解决方案5】:

        过滤器回调必须返回一个布尔值以保留元素或删除它,因此 true 表示该值通过了您的检查。

        过滤器原型的详细描述可以在这里找到。

        https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

        【讨论】:

          猜你喜欢
          • 2023-03-08
          • 1970-01-01
          • 2011-09-14
          • 2020-05-30
          • 2017-07-19
          • 1970-01-01
          • 2022-08-19
          • 2019-12-29
          • 2020-02-24
          相关资源
          最近更新 更多