javascriptroom blog

Understanding the Underscore.js `_.sortedIndex()` Function

Underscore.js is a popular JavaScript utility library that provides a wide range of useful functions for working with arrays, objects, and more. One such function is _.sortedIndex(). In this blog post, we'll explore what the _.sortedIndex() function does, how it works, and when you might want to use it.

2026-06

Table of Contents#

What is _.sortedIndex()?#

The _.sortedIndex() function in Underscore.js is used to determine the index at which a specific value should be inserted into a sorted array so that the array remains sorted. It takes two main arguments: a sorted array and a value. It returns the appropriate index position.

How Does it Work?#

Under the hood, _.sortedIndex() uses a binary search-like algorithm (although it's a simplified version for the sake of JavaScript's data types and Underscore's implementation). It compares the given value with the elements in the sorted array and finds the correct position.

Let's break it down:

  1. Initial Setup: It starts by setting some initial variables like the low and high indices of the array (initially 0 and array.length - 1 respectively).
  2. Binary Search Loop: It enters a loop where it calculates a middle index (mid) as Math.floor((low + high) / 2). Then it compares the value at the mid index of the array with the given value.
    • If the value at mid is less than the given value, it updates the low index to mid + 1.
    • If the value at mid is greater than or equal to the given value, it updates the high index to mid - 1.
  3. Return the Index: Once the loop ends (when low > high), it returns the low index, which is the position where the value should be inserted.

Example Usage#

Basic Example#

const _ = require('underscore');
 
const sortedArray = [10, 20, 30, 40, 50];
const valueToInsert = 25;
 
const index = _.sortedIndex(sortedArray, valueToInsert);
console.log(index); // Output: 2
// Now, if we insert the value at index 2, the array remains sorted: [10, 20, 25, 30, 40, 50]

With a Custom Comparator (Optional Third Argument)#

You can also provide a custom comparator function as the third argument. This is useful when you need to compare objects or values in a non-standard way.

const _ = require('underscore');
 
const sortedArrayOfObjects = [{name: 'Alice', age: 25}, {name: 'Bob', age: 30}, {name: 'Charlie', age: 35}];
const newObject = {name: 'David', age: 28};
 
const comparator = (obj1, obj2) => obj1.age - obj2.age;
 
const index = _.sortedIndex(sortedArrayOfObjects, newObject, comparator);
console.log(index); // Output: 1
// Inserting newObject at index 1 would keep the array sorted by age

Common Practices#

  • Sorting Arrays First: Always make sure the input array is actually sorted. If it's not, the result of _.sortedIndex() will be incorrect. You can use _.sortBy() or JavaScript's native sort() method (with a proper comparator if needed) to sort the array before using _.sortedIndex().
  • Error Handling: Although _.sortedIndex() is designed to work with arrays, it's a good practice to add some basic checks (like if (!Array.isArray(array)) { throw new Error('Input must be an array'); }) in your code, especially in larger applications where data integrity is crucial.

Best Practices#

  • Performance Considerations: Since it uses a binary search-like approach, _.sortedIndex() has a time complexity of $O(\log n)$ (where $n$ is the length of the array), which is efficient for large arrays. But if you are dealing with extremely large datasets (like thousands or millions of elements), you might want to benchmark and see if there are any optimizations specific to your use case (e.g., using typed arrays if applicable).
  • Code Readability: When using the custom comparator, make sure to give it a descriptive name. Also, document the purpose of the comparator function if it's complex, so that other developers (or even your future self) can easily understand how the comparison is being done.

Reference#

By understanding and using the _.sortedIndex() function effectively, you can manage sorted arrays more easily in your JavaScript projects, whether it's for data organization, implementing custom sorting-based algorithms, or working with collections that need to maintain a sorted order.