【问题标题】:Removing an element from an array with filter method.使用过滤器方法从数组中删除元素。
【发布时间】:2017-02-25 10:10:52
【问题描述】:

这是我必须做的:

您将获得一个初始数组(第一个参数在 destroyer 函数),后跟一个或多个参数。移除所有 初始数组中与这些具有相同值的元素 论据。

我的代码:

function destroyer(arr) {
  for(i=1; i < arguments.length; i++) {
  x = arr.filter(filterer);
  }

  function filterer(val) {
    return val !== arguments[i];
  }
  return x;
}

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

但它不能正常工作并返回初始数组而不是过滤后的数组。我的错在哪里?

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    基本上,你有两个问题,

    • arguments[i] 内容错误,在过滤器函数的回调中,

      function destroyer(arr) {
          function filterer(val) { // <--------------------+
              return val !== arguments[i]; //              |
              //             ^^^^^^^^^^^^ this points to --+
          }
          for(i=1; i < arguments.length; i++) {
              x = arr.filter(filterer);
          }
          return x;
      }
      
    • 没有为进一步过滤分配结果。

    解决方案

    • 在测试值上取一个带有闭包的函数,并返回一个函数以在过滤器方法中进行进一步测试。

    • 使用带有arr 的变量作为起始值并分配过滤结果。然后在最后返回这个值。

    function destroyer(arr) {         
        function filterer(testValue) {               // take arguments[i] value
            return function (val) {                  // return function as callback
                return val !== testValue;            // use testValue instead of arguments[i]
            }
        }
    
        var x = arr                                  // assign arr as start value for filtering
        for (var i = 1; i < arguments.length; i++) {
            x = x.filter(filterer(arguments[i]));    // use filterer with a parameter
        }
        return x;                                    // return result
    }
    
    console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));

    【讨论】:

    • var x = arr.slice(0) 会更好,以免改变输入数组
    • @PranavJindal filter 是一个纯函数,不会改变调用它的数组。使用slice 是不必要的,只会在此方法的开销中增加另一个数组创建。
    • @gyre 过滤器没有,但 x = x.filter(filterer(arguments[i])); 有 ?
    • @PranavJindal,不,它会创建一个新的参考。旧数组保留,请参阅编辑。
    • @PranavJindal 通过引用传递的对象不能简单地通过重新分配单个引用来销毁。只有在没有任何代码可以访问该对象的引用时,垃圾收集器才会采取行动。
    【解决方案2】:

    arguments 范围已更改。

    您想在function filterer(val) {return val !== arguments[i];} 中使用arguments[i],因为它是destroyer 的父函数的参数。

    如果是这样,使用filterer作为箭头函数来保持arguments的范围。

    function destroyer(arr) {
      const filterer = (val) => { // ?? ⚠️ This is an arrow function
        return val !== arguments[i]; // ⬅️ "arguments" refers now to "destroyer()" args
      }
      for(i=1; i < arguments.length; i++) {
         x = arr.filter(filterer);
      }
    
    
      return x;
    }
    
    destroyer([1, 2, 3, 1, 2, 3], 2, 3);
    

    【讨论】:

      【解决方案3】:

      制作参数对象的副本。正如 Abdennour 所说,过滤器的参数对象范围会发生变化。

      另外,复制输入数组并继续仅从该数组中过滤。否则您的结果将只过滤最后一个参数。

      function destroyer(arr) {
      var copy = arguments;
      var x = arr;
        for(i=1; i < copy.length; i++) {
        x = x.filter(filterer);
        }
      
        function filterer(val) {
          return val !== copy[i];
        }
        return x;
      }
      
      destroyer([1, 2, 3, 1, 2, 3], 2, 3);
      

      【讨论】:

        猜你喜欢
        • 2022-07-11
        • 2022-01-22
        • 2020-02-16
        • 2020-09-12
        • 2013-09-09
        • 2016-09-19
        • 2019-12-20
        • 2020-06-14
        • 1970-01-01
        相关资源
        最近更新 更多