Skip to content

Instantly share code, notes, and snippets.

@streetchief
Last active May 2, 2023 14:53
Show Gist options
  • Save streetchief/de27c3a3f279ecc5ccf914c0a174bb4a to your computer and use it in GitHub Desktop.
Save streetchief/de27c3a3f279ecc5ccf914c0a174bb4a to your computer and use it in GitHub Desktop.
One Filter is Better Than Two

Filter explanation (Not Peer Reviewed)

Doing a double filter (bad):

return devices.filter(thresholdFilter).filter(dateFilter)

is roughly equivalent to

const firstPassElements = [];

// touches every element in the original input
for (let i = 0; i < devices.length; i++) {
    const device = devices[i]
    if (thresholdFilter(device)) firstPassElements.push(device)
}

const secondPassElements = [];

// no guarantees are made about what is filtered above
// this will touch from 0 - n elements
for (let i = 0; i < firstPassElements.length; i++) {
    const device = devices[i]
    if (dateFilter(device)) secondPassElements.push(device)
}

// the total elements read are n + n = 2n in the worst case, 
// or n + logn average case, or more generically, n + x
return secondPassElements

Now, the better alternative:

return devices.filter(device => thresholdFilter(device) && dateFilter(device))

is roughly equivalent to

const filteredElements = [];

for (let i = 0; i < devices.length; i++) {
    const device = devices[i]
    if (thresholdFilter(device) && dateFilter(device)) filteredElements.push(device)
}

// total elements read is ALWAYS n
// and n is ALWAYS less than n + x (where x > 0)
return filteredElements;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment