Lodash _.sortedLastIndex() method
What you’ll learn
- How
_.sortedLastIndex(array, value)picks the upper insertion boundary (bisect right). - Why duplicate streaks split _.sortedIndex() and
sortedLastIndexapart. - How to bracket equal ranges using both helpers.
- Try each example in the editor (
?tryit=1,2,3) with Lodash from a CDN.
Prerequisites
Read _.sortedIndex() first for bisect-left inserts; skim _.sortedIndexOf() when you only need membership indexes.
- You are fluent with ascending ordering and half-open index intervals.
- You can run snippets in Node or open the Try-it labs in a browser.
Overview
_.sortedLastIndex mirrors engineering bisect algorithms that seek the right edge of an equal span—critical when counting duplicates, slicing histogram buckets, or aligning merge windows.
Bisect right
Insertion sits after every element strictly less than the probe—and after the whole duplicate band tied on equality.
Duplicate spans
Subtract left from right indexes to measure how many slots compare equal without scanning manually.
Non-destructive
Pure arithmetic on indexes—you splice or rebuild elsewhere using the boundary Lodash computed.
Syntax
_.sortedLastIndex(array, value) - array: ascending sorted collection probed with binary search.
- value: needle positioned using SameValueZero ordering semantics.
- Returns: greatest insertion index in
[0, array.length]that preserves ascending order.
After a duplicate run
Where _.sortedIndex hugs the left edge, sortedLastIndex advances to the slot immediately after the final equal element.
import sortedIndex from "lodash/sortedIndex";
import sortedLastIndex from "lodash/sortedLastIndex";
const xs = [10, 20, 20, 20, 30];
sortedIndex(xs, 20); // → 1
sortedLastIndex(xs, 20); // → 4 Unique middle insert
With no neighboring duplicates, bisect left and right converge—the gap between two distinct values still lands at the same index.
import sortedLastIndex from "lodash/sortedLastIndex";
sortedLastIndex([10, 20, 30], 25);
// → 2 Prepend and append
Extreme needles still yield half-open boundaries at 0 or length.
import sortedLastIndex from "lodash/sortedLastIndex";
sortedLastIndex([5, 15, 25], 2); // → 0
sortedLastIndex([5, 15, 25], 99); // → 3 📋 _.sortedLastIndex vs _.sortedIndex vs _.sortedLastIndexOf
| API | Insertion edge |
|---|---|
_.sortedIndex(array, value) | Left / lower bound (bisect left). |
_.sortedLastIndex(array, value) | Right / upper bound (bisect right). |
_.sortedLastIndexBy(array, value, iteratee) | Bisect right on projected keys (objects / derived values). |
_.sortedLastIndexOf(array, value) | Last matching element index, or -1—membership lookup, not insertion. |
Pitfalls to avoid
Descending data
Flip sort direction or swap helpers—binary search assumes ascending storage.
Confusing with sortedLastIndexOf
Insertion indexes can equal length; sortedLastIndexOf tops out at length - 1 or -1.
Rich objects
Default ordering compares references—project fields via _.sortedLastIndexBy() when ordering keys live inside structs.
❓ FAQ
Summary
- Purpose:
_.sortedLastIndex(array, value)returns the upper insertion boundary on ascending sorted input. - Counts: combine with
sortedIndexto measure duplicate bandwidth in one subtraction. - Next: Lodash _.sortedLastIndexBy(), _.sortedIndexOf() (previous), or the array methods hub.
Together _.sortedIndex() and sortedLastIndex bracket equal runs: subtract to count duplicates or reserve inclusive ranges inside sorted buffers.
6 people found this page helpful
