Prompt
Implement your own version of Array.prototype.filter as myFilter(arr, predicate).
Keep elements whose predicate result is TRUTHY (not just === true), return a new array,
and pass (element, index, array) to the predicate.
Solution
Filter is map's sibling with a different contract: instead of transforming every element, it selects a subset — output length is 0 to n, and crucially the kept elements are the same references as the input's, not copies. That identity preservation matters in practice: filtering a list of objects and then mutating one mutates the original too. A senior mentions that unprompted, because it's the bug that follows "I filtered it, so it's a new array, right?" — new array, same objects.
Two contract details the tests pin down. First, truthiness, not strict equality with true: the spec coerces the predicate's return value, which is exactly why arr.filter(Boolean) works as the idiomatic compact-the-falsy-values one-liner. Guarding with === true would break that idiom and half the predicates in real codebases. Second, the full (element, index, array) triple — index-based selection like "every other row" is a legitimate, common use.
Note what filter deliberately isn't: it can't short-circuit (that's find/some), and it always walks the whole array. Chaining filter().map() costs two passes and an intermediate array — fine almost always, worth collapsing into one reduce only when a profiler says so.
Red flag: if (predicate(arr[i]) === true). It looks defensive and is actually wrong — it silently drops every predicate that returns a truthy non-boolean, including filter(Boolean).
Say it: "Filter keeps the same element references under a truthiness test — the array is new, the objects aren't, and that distinction is where post-filter mutation bugs come from."