首页 > 解决方案 > JavaScript:多个过滤器链与复杂条件

问题描述

很多时候,您需要过滤具有多个条件的数组:

return results
  .filter(x => controlGroup[x] !== undefined)
  .filter(x => x.size > 10)

或者你可以对一个复杂的条件和一个单一 filter的做同样的事情:

return results
  .filter(x => controlGroup[x] !== undefined && x.size > 10)
// or
  .filter(x => 
    controlGroup[x] !== undefined // <- Prettier would place && here. What a joke. 101
    && x.size > 10
  )

我的猜测是,由于第二种方法不会多次迭代数组,因此它具有更好的性能特征,

另一方面,第一个在可读性方面获胜,并且可以使用简洁的 git diff LOC 轻松扩展。


在我的特殊情况下,我在 Node.js 服务器上有一个函数,每个请求对一组约 40 个项目(在 之后flat()运行 3 次。已经有很多迭代和一些 lambda 函数,所以我什至怀疑对两个过滤器进行微优化会有所作为。我相信这一切都可以只用一个来重写reduce以节省 7 次迭代(如果我计算正确的话),但代价是什么
PS:我正在寻找一般答案,但您可以回答我的特殊情况作为奖励。谢谢你。

export const getProductFeatures =
  (technicalSpecifications: TechnicalSpecifications, featuresBySpecLabel: FeaturesBySpecLabel): ProductFeature[] =>
    [...technicalSpecifications
      .map(specGroup => specGroup.specifications)
      .flat()
      .filter(spec => featuresBySpecLabel[spec.label] !== undefined)
      .filter(spec => verifyFeature(spec, featuresBySpecLabel[spec.label]))
      .reduce((productFeatures, spec) => {
        productFeatures.add(featuresBySpecLabel[spec.label].featureLabel)
        return productFeatures
      }, new Set<string>())]
      .map(label => ({ label }))

标签: javascriptarraystypescriptfilter

解决方案


根据评论,对于数组中约 40 个项目的特定情况,性能没有显着提升。

从技术上讲,在最坏的情况下,每次额外的迭代都会增加 n 倍的时间复杂度,因此使用 2 次迭代O(2n),它可能需要两倍的时间,但我们谈论的是纳米级的时间跨度,例如。10nsvs20ns在这种特殊情况下。根据数据集的大小、运行代码的机器等,可能值得考虑。

O计算符号时通常会忽略常量。即O(n)O(2n)
~ Felix Kling (取自评论)

话虽如此,性能可以排除在外,现在只剩下可读性因素,这是非常主观和基于意见的。SO 上不允许此类 QA。为了得到这个问题的答案,任何想知道的人都应该与他们的团队讨论这个问题或用心决定。不过,一般而言,对于等效代码,可读性往往更受重视,如上所示。但是,任何人认为更好的可读性取决于个人喜好或团队/公司指南。


推荐阅读