Lodash _.sortBy() — Sort Objects, Arrays & Descending Order (Examples)
Share:

Lodash _.sortBy() — Sort Objects, Arrays & Descending Order (Examples)

Amaresh Adak

By Amaresh Adak

Lodash _.sortBy() is a JavaScript utility function that creates a new sorted array in ascending order based on one or more sort criteria. For descending order, use _.orderBy() which accepts a direction parameter. Unlike the native Array.prototype.sort(), both methods return a new array without mutating the original and guarantee a stable sort.

// Ascending sort
_.sortBy(collection, [iteratees])

// Descending sort
_.orderBy(collection, [iteratees], ['desc'])

Here is a quick example showing both:

const users = [
  { name: "Charlie", age: 30 },
  { name: "Alice", age: 25 },
  { name: "Bob", age: 25 }
];

// Ascending by age
const ascending = _.sortBy(users, 'age');
// [{ Alice, 25 }, { Bob, 25 }, { Charlie, 30 }]

// Descending by age
const descending = _.orderBy(users, ['age'], ['desc']);
// [{ Charlie, 30 }, { Alice, 25 }, { Bob, 25 }]

Notice that Alice and Bob (both age 25) kept their original order — this is the stable sort guarantee that native .sort() didn't reliably provide before ES2019.

In this guide, you will learn how to use _.sortBy() and _.orderBy() to sort arrays of numbers, strings, and objects by single or multiple properties, nested values, dates, descending order, case-insensitive sorting, and custom logic. We also cover _.sortBy() vs _.orderBy() differences and native alternatives.

🔍 Also check out our guides on Lodash Merge and Lodash GroupBy for more data manipulation techniques.

How to Install and Import Lodash sortBy

Before using _.sortBy(), set up Lodash in your project:

Install the full library:

npm install lodash

Import _.sortBy() in your code:

// ES6 — import only sortBy (tree-shakable, reduces bundle size)
import sortBy from 'lodash/sortBy';
import orderBy from 'lodash/orderBy';

// CommonJS
const sortBy = require('lodash/sortBy');
const orderBy = require('lodash/orderBy');

// Or import the full library
import _ from 'lodash';
// then use _.sortBy() and _.orderBy()

Lightweight alternative — install only the sortBy module:

npm install lodash.sortby
import sortBy from 'lodash.sortby';

Tip: The full Lodash library is ~70KB (minified + gzipped). Importing lodash/sortBy or installing lodash.sortby keeps your bundle lean at ~2KB.

If you are using Lodash in the browser without a bundler:

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<script>
  const sorted = _.sortBy([3, 1, 2]);
</script>

Lodash sortBy Syntax and Parameters

Here is the complete syntax:

_.sortBy(collection, [iteratees=[_.identity]])
ParameterTypeDescription
collectionArray or ObjectThe collection to sort.
[iteratees]Function, String, or ArrayOne or more sort criteria. Can be property names (strings), functions, or an array of both.
ReturnsArrayA new sorted array. The original is not modified.

Key difference from native .sort(): _.sortBy() never mutates the original array. It always returns a new sorted array.

Sort an Array of Numbers

The simplest use case — sorting numbers in ascending order:

const numbers = [3, 1, 4, 1, 5, 9, 2, 6];

const sorted = _.sortBy(numbers);
console.log(sorted);
// Output: [1, 1, 2, 3, 4, 5, 6, 9]

console.log(numbers);
// Output: [3, 1, 4, 1, 5, 9, 2, 6]  ← original unchanged

Unlike native Array.sort(), which sorts numbers as strings by default (so 10 would come before 2), _.sortBy() handles numbers correctly out of the box.

Sort an Array of Strings

const fruits = ["banana", "apple", "cherry", "date"];

const sorted = _.sortBy(fruits);
console.log(sorted);
// Output: ["apple", "banana", "cherry", "date"]

Sort Strings by Length

const words = ["apple", "banana", "cherry", "date", "elderberry"];

const sortedByLength = _.sortBy(words, 'length');
console.log(sortedByLength);
// Output: ["date", "apple", "banana", "cherry", "elderberry"]

Lodash sortBy Case Insensitive

By default, uppercase letters sort before lowercase ("Apple" comes before "banana" because uppercase A has a lower character code). To sort case-insensitively, pass a function that converts to lowercase:

const mixed = ["Banana", "apple", "Cherry", "date", "ELDERBERRY"];

const sorted = _.sortBy(mixed, (word) => word.toLowerCase());
console.log(sorted);
// Output: ["apple", "Banana", "Cherry", "date", "ELDERBERRY"]

For arrays of objects, apply the same approach to the property:

const users = [
  { name: "charlie" },
  { name: "Alice" },
  { name: "BOB" }
];

const sorted = _.sortBy(users, (user) => user.name.toLowerCase());
console.log(sorted.map(u => u.name));
// Output: ["Alice", "BOB", "charlie"]

This ensures "Alice", "alice", and "ALICE" are treated as the same value for sorting purposes.

Sort Array of Objects by a Single Property

This is the most common use case. Pass the property name as a string:

const users = [
  { name: "Charlie", age: 30 },
  { name: "Alice", age: 25 },
  { name: "Bob", age: 28 }
];

// Sort by age
const sortedByAge = _.sortBy(users, 'age');
// Output: [{ Alice, 25 }, { Bob, 28 }, { Charlie, 30 }]

// Sort by name
const sortedByName = _.sortBy(users, 'name');
// Output: [{ Alice, 25 }, { Bob, 28 }, { Charlie, 30 }]

Sort by Multiple Fields (Multiple Properties)

When the first property values are equal, the second property acts as a tiebreaker. Pass an array of property names:

const students = [
  { name: "Alice", grade: "A", age: 22 },
  { name: "Bob", grade: "B", age: 22 },
  { name: "Charlie", grade: "A", age: 21 },
  { name: "Diana", grade: "B", age: 23 }
];

// Sort by grade first, then by age
const sorted = _.sortBy(students, ['grade', 'age']);
console.log(sorted);
// Output:
// [
//   { name: "Charlie", grade: "A", age: 21 },
//   { name: "Alice", grade: "A", age: 22 },
//   { name: "Bob", grade: "B", age: 22 },
//   { name: "Diana", grade: "B", age: 23 }
// ]

All "A" grade students come first (sorted by age within the group), followed by "B" grade students.

Sort Nested Objects

To sort by a nested property, use dot notation as a string:

const people = [
  { name: { first: "Alice", last: "Williams" }, age: 30 },
  { name: { first: "Bob", last: "Adams" }, age: 25 },
  { name: { first: "Charlie", last: "Brown" }, age: 35 }
];

const sortedByLastName = _.sortBy(people, 'name.last');
console.log(sortedByLastName.map(p => p.name.last));
// Output: ["Adams", "Brown", "Williams"]

You can also use a function for deeply nested values:

const sorted = _.sortBy(people, (person) => person.name.last);

Lodash sortBy Descending Order

_.sortBy() only sorts in ascending order. For descending order, use _.orderBy() which accepts a direction parameter:

const users = [
  { name: "Alice", age: 25 },
  { name: "Bob", age: 30 },
  { name: "Charlie", age: 22 }
];

// Descending by age
const sorted = _.orderBy(users, ['age'], ['desc']);
console.log(sorted);
// Output:
// [
//   { name: "Bob", age: 30 },
//   { name: "Alice", age: 25 },
//   { name: "Charlie", age: 22 }
// ]

For simple arrays:

const numbers = [3, 1, 4, 1, 5, 9];

// Descending numbers
const sorted = _.orderBy(numbers, [], ['desc']);
console.log(sorted);
// Output: [9, 5, 4, 3, 1, 1]

Descending with Multiple Fields

_.orderBy() lets you sort different properties in different directions:

const products = [
  { name: "Widget", price: 25, rating: 4.5 },
  { name: "Gadget", price: 25, rating: 4.8 },
  { name: "Doohickey", price: 15, rating: 4.2 }
];

// Ascending by price, descending by rating
const sorted = _.orderBy(products, ['price', 'rating'], ['asc', 'desc']);
console.log(sorted);
// Output:
// [
//   { name: "Doohickey", price: 15, rating: 4.2 },
//   { name: "Gadget", price: 25, rating: 4.8 },
//   { name: "Widget", price: 25, rating: 4.5 }
// ]

Alternative: Reverse After sortBy

If you prefer _.sortBy(), you can reverse the result:

// Method 1: _.reverse()
const sorted = _.reverse(_.sortBy(users, 'age'));

// Method 2: Negate numeric values
const sorted = _.sortBy(users, (user) => -user.age);

// Method 3: Array.reverse()
const sorted = _.sortBy(users, 'age').reverse();

Recommendation: Use _.orderBy() for descending sorts — it is cleaner and supports mixed directions.

Lodash sortBy vs orderBy — What Is the Difference?

This is one of the most commonly searched comparisons:

Feature_.sortBy()_.orderBy()
Sort directionAscending onlyAscending or descending (per field)
Syntax_.sortBy(arr, 'age')_.orderBy(arr, ['age'], ['desc'])
Mixed directions❌ Not possible['asc', 'desc'] per field
IterateesString, Function, ArrayString, Function, Array
ReturnsNew sorted arrayNew sorted array
Mutates originalNoNo
PerformanceSlightly faster (less overhead)Same O(n log n)

When to use which:

  • Use _.sortBy() when you only need ascending order — it has a simpler API
  • Use _.orderBy() when you need descending order or mixed sort directions
// These produce the same ascending result:
_.sortBy(users, 'age');
_.orderBy(users, ['age'], ['asc']);

// Only orderBy can do this:
_.orderBy(users, ['grade', 'age'], ['asc', 'desc']);

Sort by Date

JavaScript Date objects are comparable, so _.sortBy() handles them naturally:

const events = [
  { title: "Meeting", date: new Date("2025-03-15") },
  { title: "Deadline", date: new Date("2025-01-10") },
  { title: "Launch", date: new Date("2025-02-20") }
];

// Oldest first
const sorted = _.sortBy(events, 'date');

// Newest first
const sortedDesc = _.orderBy(events, ['date'], ['desc']);

For ISO date strings, sorting works correctly because ISO format is lexicographically orderable:

const posts = [
  { title: "Post C", createdAt: "2025-03-01" },
  { title: "Post A", createdAt: "2025-01-15" },
  { title: "Post B", createdAt: "2025-02-10" }
];

const sorted = _.sortBy(posts, 'createdAt');
// Output order: Post A, Post B, Post C

Custom Sorting Logic

Pass a function as the iteratee for complete control:

Sort by Computed Value

const products = [
  { name: "A", price: 100, discount: 0.1 },
  { name: "B", price: 50, discount: 0.2 },
  { name: "C", price: 80, discount: 0.05 }
];

const sorted = _.sortBy(products, (p) => p.price * (1 - p.discount));
console.log(sorted.map(p => `${p.name}: $${p.price * (1 - p.discount)}`));
// Output: ["B: $40", "C: $76", "A: $90"]

Sort with Priority Mapping

const tasks = [
  { title: "Bug fix", priority: "high", due: "2025-02-01" },
  { title: "Feature", priority: "low", due: "2025-01-15" },
  { title: "Refactor", priority: "high", due: "2025-01-20" }
];

const priorityOrder = { high: 0, medium: 1, low: 2 };

const sorted = _.sortBy(tasks, [
  (task) => priorityOrder[task.priority],
  'due'
]);
console.log(sorted.map(t => t.title));
// Output: ["Refactor", "Bug fix", "Feature"]

Handling Null and Undefined Values

_.sortBy() handles null and undefined gracefully — they sort to the end by default:

const values = [3, null, 1, undefined, 5, null, 2];

const sorted = _.sortBy(values);
console.log(sorted);
// Output: [1, 2, 3, 5, null, null, undefined]

To control placement explicitly:

// Nulls first
const nullsFirst = _.sortBy(users, (u) => (u.age == null ? -Infinity : u.age));

// Nulls last
const nullsLast = _.sortBy(users, (u) => (u.age == null ? Infinity : u.age));

Lodash sortBy vs Native Array.sort() vs toSorted()

Feature_.sortBy()Array.sort()Array.toSorted() (ES2023)
Mutates original❌ No✅ Yes❌ No
Stable sort✅ Always✅ Since ES2019✅ Stable
Sorts numbers correctly✅ Out of the box❌ Needs comparator❌ Needs comparator
Sort by property name_.sortBy(arr, 'name')❌ Needs function❌ Needs function
Multiple sort keys['a', 'b']❌ Complex comparator❌ Complex comparator
Descending order❌ Use _.orderBy()✅ Reverse comparator✅ Reverse comparator
Bundle size~2KB0KB (native)0KB (native)

Practical Examples

Sortable Table in React

import orderBy from 'lodash/orderBy';
import { useState } from 'react';

function SortableTable({ data }) {
  const [sortKey, setSortKey] = useState('name');
  const [sortDir, setSortDir] = useState('asc');

  const sortedData = orderBy(data, [sortKey], [sortDir]);

  const handleSort = (key) => {
    if (key === sortKey) {
      setSortDir(sortDir === 'asc' ? 'desc' : 'asc');
    } else {
      setSortKey(key);
      setSortDir('asc');
    }
  };

  return (
    <table>
      <thead>
        <tr>
          <th onClick={() => handleSort('name')}>
            Name {sortKey === 'name' && (sortDir === 'asc' ? '▲' : '▼')}
          </th>
          <th onClick={() => handleSort('age')}>
            Age {sortKey === 'age' && (sortDir === 'asc' ? '▲' : '▼')}
          </th>
        </tr>
      </thead>
      <tbody>
        {sortedData.map(row => (
          <tr key={row.id}>
            <td>{row.name}</td>
            <td>{row.age}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

Performance Considerations

_.sortBy() uses a modified merge sort algorithm internally:

  • Time complexity: O(n log n) — same as native .sort()
  • Space complexity: O(n) — creates a new array

Tips:

  • For arrays under 1,000 elements, performance difference is negligible
  • For 100K+ elements, native .sort() can be faster (avoids new array allocation)
  • Pre-compute expensive sort keys using the Schwartzian transform:
// ❌ Recomputes for every comparison
const sorted = _.sortBy(largeArray, (item) => expensiveCalculation(item));

// ✅ Compute once, sort, discard keys
const sorted = _.sortBy(
  largeArray.map(item => ({ item, key: expensiveCalculation(item) })),
  'key'
).map(({ item }) => item);

Tip: After sorting, you often need to group data for display. Use Lodash _.groupBy() to organize sorted results by category, and Lodash _.merge() to combine objects before sorting.

FAQs

What is the difference between Lodash sortBy and orderBy?

_.sortBy() only sorts in ascending order. _.orderBy() accepts an additional parameter to specify sort direction — 'asc' or 'desc' — for each sort key independently. Use _.sortBy() when you always want ascending order, and _.orderBy() when you need descending or mixed sort directions.

How to sort in descending order with Lodash?

Use _.orderBy() with 'desc' as the direction: _.orderBy(users, ['age'], ['desc']). Alternatively, reverse the result of _.sortBy(): _.sortBy(users, 'age').reverse(), or negate numeric values: _.sortBy(users, (u) => -u.age). The _.orderBy() approach is recommended.

Does Lodash sortBy mutate the original array?

No. _.sortBy() always returns a new sorted array. The original collection is never modified. This is different from native Array.prototype.sort(), which mutates the original array in place.

Can I sort by nested property with Lodash sortBy?

Yes. Pass the nested property path as a dot-notation string: _.sortBy(users, 'address.city'). Alternatively, pass a function: _.sortBy(users, (u) => u.address.city).

Is Lodash sortBy a stable sort?

Yes. _.sortBy() guarantees a stable sort, meaning elements with equal sort values maintain their original relative order. Native Array.sort() is also stable since ES2019.

What can I use instead of Lodash sortBy?

Native Array.prototype.toSorted() (ES2023) provides similar non-mutating behavior. For older environments, [...array].sort() creates a copy before sorting. However, _.sortBy() offers cleaner syntax for sorting by property names, multiple keys, and nested values.

Ready to Implement This in Production?

Skip the months of development and debugging. Our team will implement this solution with enterprise-grade quality, security, and performance.

Web Apps ₹25K+
Mobile Apps ₹75K+