在javascript中链接过滤器函数的好方法

时间:2018-02-16 20:19:28

标签: javascript higher-order-functions

我有大型的json对象数组,我需要根据多个用户选择输入进行过滤。目前我将过滤器功能链接在一起,但我觉得这很可能不是最有效的方法。

目前我正在这样做:

var filtered = data.filter(function(data) {
    return Conditional1
  })
  .filter(function(data) {
    return Conditional2
  })
  .filter(function(data) {
    return Conditional3
  }) etc...;

虽然(我认为)每次迭代'数据'可能会更少,我想知道更好的做法是做这样的事情:

var condition1 = Conditional1
var condition2 = Conditional2
var condition3 = Conditional3
etc...

var filtered = data.filter(function(data) {
  return condition1 && condition2 && condition3 && etc...
});

我已经研究了多个高阶函数链,特别是过滤函数 - 但我还没有看到最佳实践中的任何内容(或者不好的做法,也没有定时比较两个I&#39 ; ve建议)。

在一个具有大数据集和许多条件的用例中(我认为它们都很容易阅读)?

或许我可能缺少一种性能更高的方式(但仍使用更高阶的功能)。

5 个答案:

答案 0 :(得分:5)

将过滤器函数存储在一个数组中,让array.reduce()遍历每个过滤器,并将其应用于数据。即使没有更多数据需要过滤,也需要花费所有这些费用。

const data = [...]
const filters = [f1, f2, f3, ...]
const filteredData = filters.reduce((d, f) => d.filter(f) , data)

另一种方法是使用array.every()。这采用逆方法,遍历数据,并检查是否所有过滤器都适用。只要一个项目返回array.every()false就会返回false。

const data = [...]
const filters = [f1, f2, f3, ...]
const filteredData = data.filter(v => filters.every(f => f(v)))

两者分别与您的第一个和第二个样本相似。唯一的区别是它不会对过滤器或条件进行硬编码。

答案 1 :(得分:2)

有趣的问题



Awesome.php




还记得在for循环中,例如,在两个循环的情况下,一个3000和一个7然后:3000x7> 7x3000及时测量。

答案 2 :(得分:1)

这两个选项并不完全相同,尽管它们可以产生相同的结果

var filtered = data.filter(function(data) {
    return Conditional1
  })
  .filter(function(data) {
    return Conditional2
  })
  .filter(function(data) {
    return Conditional3
  }) etc...;

如果您想要彼此独立地检查条件,那么该选项会更好。如果在按条件2过滤之前需要按条件1过滤的数据,则应使用该数据。如果你想要的是过滤符合3个条件或它们的组合的项目,请使用第二个:

var condition1 = Conditional1
var condition2 = Conditional2
var condition3 = Conditional3
etc...

var filtered = data.filter(function(data) {
  return condition1 && condition2 && condition3 && etc...
});

答案 3 :(得分:0)

如果你认为这是一个" for-loop"优化问题,您可以看到原始方法导致多次迭代列表。

您的第二种方法会将迭代次数减少到一次。

在此之后,您只是在寻找快速决定物品是否通过集合的最佳方式。

答案 4 :(得分:-1)

不确定性能,但这些天我爱上了javascript中的reduce方法。像这样:

arr.reduce((itemMap, item) => {
    if (item.something !== somethingElse) return itemMap;
    return itemMap.push(item);
}, [])

这基本上类似于.filter,但您可以做更多的事情。就像您甚至想映射一些值一样,您可以通过更新item对象并在所有条件匹配的情况下返回该项目来实现。 虽然,不确定性能如何。