从数组中筛选出特定值

Filtering out specific values from an array

本文关键字:筛选 数组      更新时间:2023-09-26

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);

参数用于获取当前函数的参数列表。在执行您使用的参数的筛选时,它给出了筛选方法的参数。它不同于destroyer方法参数

因此,将destroyer方法参数存储在一个变量中。试试这个代码。

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));

希望这对你有帮助。

您可以使用lodash库中的difference函数。这是一个经过充分测试并广泛使用的实用程序库。

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

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

ES6允许通过引入不绑定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]