过滤一次或过滤多次

Filter once or filter multiple times

我有一个包含对象的数组:

objects = [a, b, c, ...]

对于给定的对象,我有许多 returns true/false 的函数

functions = [f1, f2, f3, ...]

现在我想获取所有传递所有函数的对象。什么最有效?

functions.forEach(function(f) {
       objects = objects.filter(f);
})

objects = objects.filter(function(o) {
       functions.forEach(function(f) {
            if(!f(o)) return false;
       })
})

我不确定什么是最有效的,这取决于过滤功能的重量?它们是一样的吗?

在这两种情况下,您都为每个函数调用 objects.filter,复杂度是相同的。如果您对先前过滤器的结果使用 filter 而不是每次都将其应用于所有对象,则可以稍微优化一下。

for (f in functions){
    objects = objects.filter(functions[f])
}

如果可能,请按时间复杂度 将函数排序为 return 为真(升序)的概率。

我做了个小测试:

  console.time("Creating objects");
  var objects1 = [];
  var objects2 = [];
  while (objects1.length < 20000) {
    var value = 1000 * Math.random();
    objects1.push({ value: value });
    objects2.push({ value: value });
  }
  console.timeEnd("Creating objects");

  console.time("Creating functions")
  var functions = [];
  while (functions.length < 1000) {
    var rnd_value = 1000 * Math.random();
    functions.push(function(o) {
        return o.value >= rnd_value;
    });
  }
  console.timeEnd("Creating functions")

  console.time("Functions outer")

  functions.forEach(function(f) {
    objects1 = objects1.filter(f);
  });

  console.timeEnd("Functions outer");

  console.time("Filter outer")

  objects2 = objects2.filter(function(o) {
    var ret = true;
    functions.forEach(function(f) {
      if (ret && !f(o)) ret = false;
    });
    return ret;
  });

  console.timeEnd("Filter outer");

控制台的结果是: 外部函数:3188.918ms 过滤器外部:454.249ms

所以我假设数组的过滤函数在 javascript 中相当繁重。换句话说,我应该尽可能少地调用它。