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). 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.
Is there another way to do this, and still have a predicate with no variables outside the predicate 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" ]
CodePudding user response:
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.
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()))
CodePudding user response:
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)
}