How Lodash findLast Searches Collections from the End
This article provides an overview of the _.findLast
method in the Lodash JavaScript library, explaining how it traverses
collections in reverse order to locate specific elements. You will learn
the underlying mechanics of how the function iterates backwards, its
syntax and parameters, how it handles performance through early
termination, and practical examples demonstrating its usage with both
arrays and objects.
Syntax and Parameters
The _.findLast method allows developers to inspect a
collection from right to left (or bottom to top for objects). The syntax
is as follows:
_.findLast(collection, [predicate=_.identity], [fromIndex=collection.length-1])collection: The array or object to iterate over.predicate: The condition invoked per iteration. It can be a custom function, an object property-value pair, or a property name.fromIndex: An optional parameter indicating the index from which to start the reverse search. By default, it begins at the final index (collection.length - 1).
How the Reverse Search Works
Unlike standard search functions like JavaScript's native
Array.prototype.find or Lodash’s _.find, which
start at index 0 and increment upwards,
_.findLast works in reverse:
- Initial Index Calculation: The method establishes
the starting point. If no
fromIndexis provided, it targets the last index of the array (collection.length - 1). If a negativefromIndexis provided, it is treated as an offset from the end of the collection. - Reverse Iteration: A loop decrements the index
counter sequentially toward index
0. - Predicate Evaluation: At each index, Lodash invokes
the predicate with three arguments: the current value
(value), the current index or key(index|key), and the entirecollection. - Short-Circuiting: The moment the predicate returns
a truthy value,
_.findLastimmediately stops the iteration and returns that specific element. Remaining elements closer to the beginning of the collection are never evaluated. - Fallback to Undefined: If the loop reaches the
beginning of the collection without finding a truthy condition, the
method returns
undefined.
Code Example: Basic Reverse Search
In this example, _.findLast locates the last even number
in an array:
const numbers = [1, 2, 3, 4, 5, 6, 7];
const lastEven = _.findLast(numbers, n => n % 2 === 0);
console.log(lastEven); // Output: 6Because the iteration begins at 7 and moves backwards,
6 is the first even number encountered, causing the loop to
terminate immediately without checking 4 or
2.
Code Example: Objects and Shorthand Predicates
Lodash supports various shorthand formats for the predicate argument, such as matching object key-value pairs:
const users = [
{ id: 1, user: 'barney', active: true },
{ id: 2, user: 'fred', active: false },
{ id: 3, user: 'pebbles', active: true }
];
// Search using property-value shorthand
const lastActiveUser = _.findLast(users, { active: true });
console.log(lastActiveUser);
// Output: { id: 3, user: 'pebbles', active: true }Using the fromIndex
Offset
You can restrict the search range by defining where the backwards scan should begin:
const items = [10, 20, 30, 40, 50];
// Start searching backwards from index 2 (value: 30)
const result = _.findLast(items, n => n < 35, 2);
console.log(result); // Output: 30Why Use
_.findLast Instead of Reversing First?
A common alternative pattern is chaining
.reverse().find(). However, _.findLast
provides two major advantages:
- Immutability: Standard methods like
Array.prototype.reverse()mutate the original array in place, which often leads to unintended side effects. - Memory and Performance Efficiency: Making a copy of
an array just to reverse it allocates extra memory.
_.findLastreads the original array directly in reverse order, consuming \(O(1)\) additional memory and avoiding unnecessary operations via early termination.