过滤掉数组中的特定值

时间:2015-11-28 11:46:14

标签: javascript arrays function web

destroyer([1, 2, 3, 1, 2, 3], 2, 3)应返回[1, 1],但会返回[1, 2, 3, 1, 2, 3]。这段代码有什么问题?

function destroyer(arr) {
  // Remove all the values
  var arg_num = arguments.length;

  var new_arr = arguments[0].filter(function(a){
    for (var i = 1; i < arg_num; i++){
      if (a === arguments[i]) a = false; 
    }
    return a;
  });

  return new_arr;
}

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

3 个答案:

答案 0 :(得分:2)

参数用于获取当前函数的参数列表。在执行过滤器时使用了参数,它给出了filter方法的参数。它与驱逐舰方法论证不同。

因此将驱逐舰方法参数存储在一个变量中。 试试这段代码。

function destroyer(arr) {
// Remove all the values
var args = arguments;
var arg_num = args.length;
var flag;
var new_arr = arguments[0].filter(function (a) {
  flag = false;
  for (var i = 1; i < arg_num; i++) {
    if (a === args[i]) {
      flag = true;
      break;
    };
  }
  if (flag)
    return false;
  else
    return true;
});
return new_arr;
}
console.log(destroyer([0, 2, 3, 0, 2, 3], 0, 3));

希望这会对你有所帮助。

答案 1 :(得分:1)

问题是arguments关键字通常绑定到当前函数,在本例中是filter中使用的匿名函数。

ES6允许通过引入arrow functions, which don't bind arguments轻松解决此问题。

(function destroyer(arr) {
  var arg_num = arguments.length;
  return arguments[0].filter(a => {
    for (var i = 1; i < arg_num; i++){
      if (a === arguments[i]) return false;
    }
    return true;
  });
})([1, 2, 3, 1, 2, 3], 2, 3); // [1, 1]

但是,请注意此函数的开销为n m,其中n是数组中元素的数量,m是其他参数的数量。但可能会更好。

例如,如果其他参数始终为数字,则可以对它们进行排序,然后使用二分法搜索。这将花费n lg(m)

另一种方法是使用哈希表。在最坏的情况下仍会花费n m,但平均只有n

如果您不想手动实施,可以使用ES6套装。其具体成本将取决于实现,但平均要求为次线性。

(function destroyer(arr, ...args) {
  var s = new Set(args);
  return arr.filter(a => !s.has(a));
})([1, 2, 3, 1, 2, 3], 2, 3); // [1, 1]

答案 2 :(得分:1)

您可以使用difference库中的lodash功能。它是一个经过良好测试和广泛使用的实用程序库。

var _ = require('lodash');

var result = _.difference([1, 2, 3, 1, 2, 3], [2, 3])); // returns [1, 1]