Complete JavaScript Course Module 6: Intermediate: Arrays

Sorting, Slicing and Copying Arrays

  • Beginner
  • Lesson 6.3
  • 5 min read
  • 26 of 76 in the course

In short

This lesson shows how to sort JavaScript arrays correctly, cut out parts with slice and splice, and copy arrays without changing the original by accident. Mutating vs non-mutating array methods Some array methods change the original array. This is called mutating.

This lesson shows how to sort JavaScript arrays correctly, cut out parts with slice and splice, and copy arrays without changing the original by accident.

Mutating vs non-mutating array methods

Some array methods change the original array. This is called mutating. Others leave the original alone and return a new array. Knowing which is which saves you from confusing bugs, like a list on your page suddenly changing order.

Think of it like editing a document. A mutating method writes on the original paper. A non-mutating method makes a photocopy and writes on the copy.

What is the difference between slice and splice?

The names look alike, but they behave very differently.

  • slice(start, end) returns a copy of part of the array. The item at end is not included. The original is not changed.
  • splice(start, deleteCount, ...items) changes the original array. It removes items and can insert new ones in their place. It returns the removed items.
const months = ["Jan", "Feb", "Mar", "Apr", "May"];

const spring = months.slice(2, 4);
console.log(spring);  // Output: ["Mar", "Apr"]
console.log(months);  // Output: ["Jan", "Feb", "Mar", "Apr", "May"]

console.log(months.slice(-2)); // Output: ["Apr", "May"]

const removed = months.splice(1, 2, "FEB", "MAR");
console.log(removed); // Output: ["Feb", "Mar"]
console.log(months);  // Output: ["Jan", "FEB", "MAR", "Apr", "May"]

slice(2, 4) takes indexes 2 and 3. A negative start counts from the end. splice(1, 2, "FEB", "MAR") goes to index 1, removes 2 items, and inserts the two new ones.

Tip: Remember "splice" like splicing film: you cut into the original. "slice" is like taking a slice of cake to your plate; the cake stays on the table.

How to sort an array in JavaScript

sort() sorts the array in place (it mutates). By default it turns every item into a string and compares them as text. That works for simple words, but it gives strange results for numbers.

const scores = [100, 25, 3, 42];
scores.sort();
console.log(scores);
// Output: [100, 25, 3, 42]  (sorted as text: "1" < "2" < "3" < "4")

To sort numbers, pass a compare function. It receives two items, a and b, and returns a number:

  • negative: a comes first
  • positive: b comes first
  • 0: keep their order

a - b does exactly this for numbers.

const prices = [19.99, 5, 120, 42];

prices.sort((a, b) => a - b);
console.log(prices); // Output: [5, 19.99, 42, 120]

prices.sort((a, b) => b - a);
console.log(prices); // Output: [120, 42, 19.99, 5]

const cities = ["Zürich", "berlin", "Amsterdam", "Ålesund"];
cities.sort((a, b) => a.localeCompare(b));
console.log(cities);
// Output: ["Ålesund", "Amsterdam", "berlin", "Zürich"]

a - b sorts low to high, and b - a sorts high to low. For strings, localeCompare compares text the way people expect, handling uppercase, lowercase and accented letters sensibly. The exact order of letters like "Å" depends on the language settings of the browser.

You can sort objects by one of their properties too:

const products = [
  { name: "Lamp", price: 30 },
  { name: "Desk", price: 150 },
  { name: "Chair", price: 85 },
];

products.sort((a, b) => a.price - b.price);
console.log(products.map((p) => p.name));
// Output: ["Lamp", "Chair", "Desk"]

Common mistake: Calling sort() on numbers without a compare function. [10, 9, 1].sort() gives [1, 10, 9]. Always use (a, b) => a - b for numbers.

reverse, toSorted and toReversed

reverse() flips the order of the array in place. Like sort, it mutates.

Modern JavaScript added safer versions that return a new array: toSorted() and toReversed(). They are supported in all current browsers.

const ratings = [4, 1, 5, 3];

const sorted = ratings.toSorted((a, b) => a - b);
const reversed = ratings.toReversed();

console.log(sorted);   // Output: [1, 3, 4, 5]
console.log(reversed); // Output: [3, 5, 1, 4]
console.log(ratings);  // Output: [4, 1, 5, 3]  (unchanged)

Use toSorted when you want to show a sorted view but keep the original order, for example "sort by price" in an online shop with a "reset" button.

How to join, combine and copy arrays

A few more useful non-mutating methods:

  • concat joins arrays into a new one.
  • join(separator) turns an array into a single string.
  • flat() flattens nested arrays by one level (or more, if you pass a depth).
  • The spread syntax [...array] copies an array. The three dots "spread out" the items into a new array.
const fruits = ["apple", "pear"];
const veggies = ["carrot", "leek"];

const groceries = fruits.concat(veggies);
console.log(groceries); // Output: ["apple", "pear", "carrot", "leek"]

console.log(groceries.join(", ")); // Output: apple, pear, carrot, leek

const nested = [1, [2, 3], [4, [5]]];
console.log(nested.flat());   // Output: [1, 2, 3, 4, [5]]
console.log(nested.flat(2));  // Output: [1, 2, 3, 4, 5]

const copy = [...fruits];
copy.push("kiwi");
console.log(fruits); // Output: ["apple", "pear"]
console.log(copy);   // Output: ["apple", "pear", "kiwi"]

const combined = [...fruits, ...veggies];
console.log(combined.length); // Output: 4

Notice that pushing to copy did not change fruits. If you had written const copy = fruits;, both names would point to the same array, and changing one would change the other.

Here is a summary table:

Mutates the originalReturns a new array or value
push, pop, shift, unshiftslice, concat, join
splicemap, filter, flat
sorttoSorted
reversetoReversed
assigning arr[i] = x[...arr] (spread copy)

Note: The MDN page on copying methods vs mutating methods has the full list.

Practice exercise

Start with const temps = [18, 25, 9, 31, 22];.

  1. Make a new array sorted from coldest to hottest without changing temps.
  2. Get the three hottest values using your sorted array and slice.
  3. Use join to log them as "31°C, 25°C, 22°C".
  4. Log temps at the end to check it is unchanged.

Hint: Sort high to low with toSorted((a, b) => b - a), then slice(0, 3), then map each number to a string before join.

Key takeaways

  • slice copies part of an array; splice changes the original by removing or inserting items.
  • sort and reverse mutate; toSorted and toReversed return new arrays.
  • Sort numbers with (a, b) => a - b and strings with a.localeCompare(b).
  • concat, join and flat combine or reshape arrays without mutating.
  • Copy an array with [...arr]; plain = only makes a second name for the same array.