Start learning free

LESSON 116 OF 675 · ARRAYS I

Slicing an Array in TypeScript with slice

Lesson Read the full explanation

TL ; DR:

arr.slice(i, j) returns a new array with the items from index i up to, not including, j. The original array doesn't change.


let letters = ["a", "b", "c", "d", "e"];

let middle = letters.slice(1, 4);
// middle is ["b", "c", "d"]

// letters is still ["a", "b", "c", "d", "e"]


Full lesson:

Sometimes you need only part of an array, like the first few items. The slice method copies that part into a new array.

Give it the start index and the end index. The item at the end index is not included. So letters.slice(1, 4) has the items at 1, 2 and 3.

That makes the length easy to see: 4 - 1 = 3 items.

To go to the very end, use the length as the end index:

let tail = letters.slice(3, letters.length);
// tail is ["d", "e"]

You may also leave the end out. So letters.slice(3) gives the same ["d", "e"].

The original array stays as it was.

Don't mix up slice and splice. The slice method copies a part and leaves the array alone. But splice changes the array itself.


Your task

runners holds a race's runners, in the order they finished.

Put the first three in a new array named podium. Put everyone else, from index 3 to the end, in one named rest.

The code below prints both, then the length of runners.

Expected output:

Ana Ben Cleo
Dan Eve
5
STEP 1 OF 2
    Ctrl + Enter to check

    TYPESCRIPT · ARRAYS I

    Array Slicing in TypeScript, explained

    What slice does

    Sometimes you need only part of an array, such as the first few items. slice(i, j) copies the items from index i up to, but not including, index j into a new array. The original array stays as it was.

    let letters = ["a", "b", "c", "d", "e"];
    console.log(letters.slice(1, 4), letters);
    [ 'b', 'c', 'd' ] [ 'a', 'b', 'c', 'd', 'e' ]

    The end index is not included, so the length of the result is simply j - i: 4 - 1 = 3 items.

    Going to the end

    Use the length as the end index to run to the end, or leave the end out:

    console.log(letters.slice(3, letters.length), letters.slice(3));
    [ 'd', 'e' ] [ 'd', 'e' ]

    An end past the length is not an error: letters.slice(1, 100) gives [ 'b', 'c', 'd', 'e' ]. And when the start is not before the end, the result is empty: letters.slice(4, 1) gives [].

    The exercise, step by step

    runners holds five runners in finishing order. The first three go on the podium and everyone else is the rest.

    1. Podium. Slice from index 0 up to 3. Index 3 is not included, so you get the items at 0, 1 and 2.
    2. Rest. Slice from index 3 up to runners.length. The length is one past the last index, so the copy runs to the end.
    let runners: string[] = ["Ana", "Ben", "Cleo", "Dan", "Eve"];
    let podium: string[] = runners.slice(0, 3);
    let rest: string[] = runners.slice(3, runners.length);
    console.log(podium[0], podium[1], podium[2]);
    console.log(rest[0], rest[1]);
    console.log(runners.length);
    Ana Ben Cleo
    Dan Eve
    5

    The last line prints 5 because slice copies and never removes anything from runners.

    Traps

    • The end index is excluded. slice(0, 3) has 3 items, not 4.
    • slice versus splice. slice copies a part and leaves the array alone, while splice changes the array itself.
    • A negative index counts from the end. letters.slice(-2) gives the last two items, [ 'd', 'e' ].
    • The copy is shallow. For numbers and strings that makes no difference. If the items are objects, the new array holds the same objects.

    Useful patterns

    Think of the two indexes as cut points placed between items, not as items. In slice(0, 3) the first cut is before index 0 and the second is before index 3, so everything between the cuts is copied. This is also why slice(3, 3) is empty: the two cuts are in the same place.

    The same method gives the first few items, the last few, or a whole copy:

    console.log(letters.slice(0, 2), letters.slice(letters.length - 2));
    const copy = letters.slice();
    copy.push("f");
    console.log(letters, copy);
    [ 'a', 'b' ] [ 'd', 'e' ]
    [ 'a', 'b', 'c', 'd', 'e' ] [ 'a', 'b', 'c', 'd', 'e', 'f' ]

    With no arguments, slice() copies the whole array. Adding "f" to the copy leaves letters untouched, so a copy is the safe way to change an array while keeping the original.

    Because the new array is separate, changing it does not change the array it came from. That is what makes the podium and the rest in the exercise independent of runners.

    Another common slip is to call runners.slice(0, 3) and not store the result. The call returns a new array, and runners itself does not change, so unless the result goes into a variable such as podium, it is thrown away. Likewise, expecting runners to shrink after taking the podium is a mistake: to take items out of the original you would need splice.

    Key takeaways

    • arr.slice(i, j) returns a new array with the items at i to j - 1.
    • arr.slice(i) runs from i to the end.
    • The original array does not change.
    Keep going with TypeScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free