Skip to main content

How to Sort an Array of Objects by a Boolean Property in JavaScript

Sorting an array of objects based on a boolean property is a common task, often used to group "active" or "completed" items together. For example, you might want to display all isComplete: true tasks at the top or bottom of a to-do list.

This guide will demonstrate the modern and most effective way to sort an array by a boolean property using the Array.prototype.sort() method with a custom comparison function that leverages boolean-to-number conversion.

The Core Method: sort() with a Custom Comparator

The Array.prototype.sort() method is the standard tool for sorting arrays in JavaScript. To sort by a specific or complex criterion (like a boolean property), you must provide it with a comparison function.

Problem: you have an array of task objects, and you want to sort them so that all the completed tasks (isComplete: true) appear first.

// Problem: Sort this array to group all `isComplete: true` objects at the top.
let tasks = [
{ id: 1, name: 'Task 1', isComplete: false },
{ id: 2, name: 'Task 2', isComplete: true },
{ id: 3, name: 'Task 3', isComplete: false },
{ id: 4, name: 'Task 4', isComplete: true },
];

Solution: the comparison function accesses the boolean property on the two objects being compared (a and b), converts them to numbers, and subtracts them.

let tasks = [
{ id: 1, name: 'Task 1', isComplete: false },
{ id: 2, name: 'Task 2', isComplete: true },
{ id: 3, name: 'Task 3', isComplete: false },
{ id: 4, name: 'Task 4', isComplete: true },
];

// Sort with `true` values first (descending order)
tasks.sort((a, b) => Number(b.isComplete) - Number(a.isComplete));

console.log(tasks);

Output:

[
{ id: 2, name: 'Task 2', isComplete: true },
{ id: 4, name: 'Task 4', isComplete: true },
{ id: 1, name: 'Task 1', isComplete: false },
{ id: 3, name: 'Task 3', isComplete: false }
]

The Key Concept: Converting Booleans to Numbers

The logic of the comparison function (a, b) => Number(b.bool) - Number(a.bool) relies on how JavaScript converts booleans to numbers:

  • Number(true) evaluates to 1.
  • Number(false) evaluates to 0.

The sort() method's comparison function expects a return value to determine the order:

  • Positive (> 0): b should come before a.
  • Negative (< 0): a should come before b.
  • Zero (0): The order of a and b remains unchanged relative to each other.

Let's see how Number(b.isComplete) - Number(a.isComplete) works when we want true values first:

  • If b.isComplete is true (1) and a.isComplete is false (0), the result is 1 - 0 = 1 (positive). So, b (the true object) is sorted before a.
  • If b.isComplete is false (0) and a.isComplete is true (1), the result is 0 - 1 = -1 (negative). So, a (the true object) is sorted before b.
note

This simple subtraction perfectly handles the sorting logic.

The Solution: A Reusable Sort Function

It's a good practice to encapsulate this logic into a reusable function that can handle both ascending and descending order.

/**
* Sorts an array of objects by a boolean property.
* @param {Array<object>} arr The array to sort.
* @param {string} key The name of the boolean property to sort by.
* @param {'trueFirst' | 'falseFirst'} order The desired sort order.
*/
function sortByBoolean(arr, key, order = 'trueFirst') {
// Create a shallow copy to avoid mutating the original array
let sorted = [...arr];

if (order === 'trueFirst') {
// For `true` first, sort in descending order (1 before 0)
sorted.sort((a, b) => Number(b[key]) - Number(a[key]));
} else {
// For `false` first, sort in ascending order (0 before 1)
sorted.sort((a, b) => Number(a[key]) - Number(b[key]));
}

return sorted;
}

// Example Usage:
let tasks = [
{ name: 'Task 1', isComplete: false },
{ name: 'Task 2', isComplete: true },
];

let trueFirst = sortByBoolean(tasks, 'isComplete', 'trueFirst');
console.log(trueFirst.map(t => t.name)); // Output: ['Task 2', 'Task 1']

let falseFirst = sortByBoolean(tasks, 'isComplete', 'falseFirst');
console.log(falseFirst.map(t => t.name)); // Output: ['Task 1', 'Task 2']

Output:

['Task 2', 'Task 1']
['Task 1', 'Task 2']

A Note on Mutability (Creating a Copy First)

The Array.prototype.sort() method sorts an array in place, meaning it mutates (modifies) the original array. This can lead to unexpected bugs if other parts of your code rely on the original order.

note

Recommended Best Practice: Always create a shallow copy of the array before sorting it if you do not intend to modify the original. The easiest way to do this is with the spread syntax (...).

let originalArray = [{ bool: true }, { bool: false }];

// Create a copy before sorting to preserve the original.
let sortedArray = [...originalArray].sort((a, b) => Number(b.bool) - Number(a.bool));

Conclusion

Sorting by a boolean property in JavaScript is a simple task once you leverage the implicit conversion of booleans to numbers.

  • The recommended best practice is to use the sort() method with a custom comparison function:
    • To sort with true values first, use (a, b) => Number(b.yourKey) - Number(a.yourKey).
    • To sort with false values first, use (a, b) => Number(a.yourKey) - Number(b.yourKey).
  • Always create a copy of your array (e.g., with [...arr]) before sorting if you want to avoid mutating the original data.