How Lodash _.filter Preserves Matching Elements

The _.filter method in the Lodash JavaScript library is designed to iterate through a collection and extract elements that satisfy a specific condition, returning them in a brand-new array. This article breaks down the internal mechanism of _.filter, explaining how it evaluates truthiness via predicate functions, guarantees original order, maintains immutability, and shallow-copies matching values directly into the result set.

Core Mechanism of _.filter

Lodash's _.filter operates as a non-destructive iteration utility. It traverses an array or object from start to finish, evaluates each value against a designated predicate function, and stores the values that pass the test into an internally created array.

The process follows a deterministic sequence:

  1. Initialization: Lodash instantiates an empty array ([]) to hold the matching results.
  2. Iteration: The method sequentially loops through the elements of the target collection using standard zero-indexed iteration for arrays or key-enumeration for objects.
  3. Predicate Invocation: For each element, Lodash calls the predicate callback, passing three arguments: the current element (value), the current index or key (index/key), and the entire source collection (collection).
  4. Truthiness Check: The returned result of the predicate is evaluated for truthiness. In JavaScript, any value other than false, 0, "", null, undefined, and NaN is considered truthy.
  5. Collection and Preservation: If the predicate returns a truthy value, Lodash pushes that exact element reference into the newly created array. If the predicate returns a falsy value, the element is skipped.
  6. Return: Once iteration is complete, the new array containing only the preserved elements is returned.

Immutability and Shallow Copying

A key characteristic of how _.filter preserves elements is immutability. The original collection remains completely untouched.

When an element passes the predicate test, Lodash preserves it via a shallow copy. For primitive values (such as numbers, strings, and booleans), the value is copied directly. For complex types (such as objects or nested arrays), Lodash preserves the direct memory reference to that object. This ensures optimal memory performance, though modifying a nested property on a filtered object will reflect in the original collection.

Order Preservation

Lodash guarantees the preservation of sequence. Because _.filter evaluates elements in order from the first index (0) to the final index (length - 1), the matching elements are placed into the output array in the exact relative order in which they appeared in the source collection.

Predicate Shorthands

Beyond custom callback functions, Lodash enhances matching preservation through built-in predicate shorthands:

Practical Example

const users = [
  { id: 1, name: 'Alice', active: true },
  { id: 2, name: 'Bob', active: false },
  { id: 3, name: 'Charlie', active: true }
];

// Preserves elements where 'active' is true
const activeUsers = _.filter(users, (user) => user.active);

// Result:
// [
//   { id: 1, name: 'Alice', active: true },
//   { id: 3, name: 'Charlie', active: true }
// ]

In this execution, users[0] and users[2] return truthy evaluations, prompting Lodash to append their references to the result array in their original chronological order, leaving users unchanged.