JavaScript
Array Sorting
reduce function
JavaScript Programming
Coding Tutorial

Sorting Array with JavaScript reduce function

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

JavaScript arrays already have a built-in sort method, so using reduce to sort is not the normal production answer. Even so, it is a useful exercise because it forces you to think about how ordered output is built one item at a time. A reduce-based sort usually works by inserting each element into the correct position in an accumulator that stays sorted as the reduction proceeds.

That makes the code educational, but not especially efficient. In most real applications, prefer sort unless you specifically need a custom reduction pattern or you are learning how accumulation-based transforms work.

Build a Sorted Accumulator

The core idea is simple: start with an empty array, then place each incoming value into the correct slot inside the accumulator.

javascript
1const numbers = [5, 1, 9, 3, 7];
2
3const sorted = numbers.reduce((acc, value) => {
4  const index = acc.findIndex((item) => item > value);
5
6  if (index === -1) {
7    acc.push(value);
8  } else {
9    acc.splice(index, 0, value);
10  }
11
12  return acc;
13}, []);
14
15console.log(sorted); // [1, 3, 5, 7, 9]

This works because acc is always kept in sorted order. Each new number is inserted before the first larger value.

The code is readable, but notice that it mutates the accumulator with push and splice. That is fine inside a reducer as long as the mutation is intentional and local.

Write an Immutable Version

If you prefer a more functional style, return a new array each time instead of mutating the accumulator.

javascript
1const numbers = [5, 1, 9, 3, 7];
2
3const sorted = numbers.reduce((acc, value) => {
4  const index = acc.findIndex((item) => item > value);
5
6  if (index === -1) {
7    return [...acc, value];
8  }
9
10  return [
11    ...acc.slice(0, index),
12    value,
13    ...acc.slice(index),
14  ];
15}, []);
16
17console.log(sorted);

This version avoids local mutation, but it creates more intermediate arrays. That makes it elegant for demonstration, but not ideal for large inputs.

Compare It With Built-In sort

Here is the equivalent using the tool that JavaScript already gives you:

javascript
const numbers = [5, 1, 9, 3, 7];
const sorted = [...numbers].sort((a, b) => a - b);
console.log(sorted);

For everyday code, this is usually the better answer. It is shorter, clearer to most JavaScript developers, and generally more efficient than inserting one item at a time during reduce.

So why learn the reducer version at all? Because it teaches three useful ideas:

  • an accumulator can represent partial ordered state
  • 'reduce can build complex structures, not just sums'
  • the algorithmic cost of an operation matters even when the code looks compact

Sorting Objects With reduce

The same insertion approach works for objects if you compare on a property.

javascript
1const users = [
2  { name: "Mina", score: 42 },
3  { name: "Raj", score: 17 },
4  { name: "Eli", score: 31 },
5];
6
7const sortedUsers = users.reduce((acc, user) => {
8  const index = acc.findIndex((item) => item.score > user.score);
9
10  if (index === -1) {
11    acc.push(user);
12  } else {
13    acc.splice(index, 0, user);
14  }
15
16  return acc;
17}, []);
18
19console.log(sortedUsers);

That makes the pattern more generally useful, especially if the accumulator logic is part of a bigger transformation pipeline.

Know the Performance Tradeoff

A reduce-based insertion sort is usually O(n^2). For each new item, you may scan part of the accumulator and then shift elements to insert it.

That is fine for short arrays and educational examples. It is a poor choice for large collections when built-in sort is available.

If performance matters, use the simpler and more direct tool. reduce is interesting here because it demonstrates control flow and accumulator design, not because it beats the native sort implementation.

Common Pitfalls

The most common mistake is forgetting to provide an empty array as the reducer's initial value. Without it, the first array element becomes the accumulator and the logic breaks.

Another issue is assuming reduce makes the algorithm more elegant just because it is shorter. In this case, the native sort call is usually clearer.

A third problem is mutating the original input by accident. If you compare results with sort, remember that sort mutates the array unless you copy it first.

Summary

  • A reduce-based sort works by keeping the accumulator ordered and inserting each new value in the right place.
  • The approach is useful for learning how reducers build structured results.
  • An immutable version is possible, but it creates more intermediate arrays.
  • Built-in sort is usually the better production tool.
  • The reduce approach is typically O(n^2), so use it with clear intent.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.