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;