简体   繁体   English

过滤谓词在遇到数字后过滤所有项目

[英]Filter predicate that filters all items after it's encountered a number

Below I have an array filter predicate that will remove all items when it encounters a number, including the number.下面我有一个数组过滤谓词,它将在遇到数字时删除所有项目,包括数字。 I'm worried about the performance of this predicate as it runs the entire filter many more times then it needs to (forgive me I don't know the bigO).我担心这个谓词的性能,因为它运行整个过滤器的次数超过了它需要的次数(请原谅我不知道 bigO)。 This is because if I want the global state of when it's encountered the number within the predicate I have to access the third argument which is the entire array.这是因为如果我想要全局 state 在遇到谓词中的数字时,我必须访问第三个参数,即整个数组。

Is there another way to do this, and still have a predicate with no variables outside the predicate scope?还有另一种方法可以做到这一点,并且在谓词 scope 之外仍然有一个没有变量的谓词?

const filterNumberOrAfter = (_: any, index: number, array: any[]): boolean => {
  let encounterdNumber = false
  const total = array.filter((path) => {
    if (encounterdNumber) return false
    if (typeof path === 'number') {
      encounterdNumber = true
      return false
    }
    return true
  })
  return Boolean(total[index])
}

console.log(['hello', 'world', 'meow', 2, 'example', 'rest'].filter(filterNumberOrAfter))
// [ "hello", "world", "meow" ]

One way to optimize is by encapsulating the predicate within a function and caching the initial run of the filter in the parent scope that way each iteration of the filter has access to the original filtered array that only ran once.一种优化方法是将谓词封装在 function 中,并将过滤器的初始运行缓存在父 scope 中,这样过滤器的每次迭代都可以访问仅运行一次的原始过滤数组。

const filterNumberOrAfter = () => {
  let total: string[] = []
  return (_: any, index: number, array: any[]): boolean => {
    if (index === 0) {
      let encounterdNumber = false
      total = array.filter((path) => {
        if (encounterdNumber) return false
        if (typeof path === 'number') {
          encounterdNumber = true
          return false
        }
        return true
      })
    }
    return Boolean(total[index])
  }
}

console.log(['hello', 'world', 'meow', 2, 'example', 'rest'].filter(filterNumberOrAfter()))

The the commenters credit, this is a nice oneliner that is much easier to read.评论者认为,这是一个很好的单行线,更容易阅读。

const getItemsTillNumber = (arr: any[]) => {
  return arr.slice(0, arr.findIndex((item) => typeof item === 'number') || arr.length)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM