Array.splice() & Array.slice()
Tags: javascript, codenewbie, tutorial, beginners
Published: 2021-08-17 18:17:13

Hello Dear Readers,

In the previous posts of this series, we've already learnt how to *add* elements to an array using `array.unshift()` & `array.push()` methods and *remove* elements from an array using `array.shift()` & `array.pop()` methods. 
https://dev.to/swarnaliroy94/add-items-to-arrays-with-unshift-push-methods-3ma2 
https://dev.to/swarnaliroy94/remove-items-from-arrays-with-shift-pop-methods-5caf

Now, what if we want *one or more than one* item to be removed from somewhere in the *middle* of an array, that too at the same time? 
Well, that's exactly where `array.splice()` comes in. 

### Array.splice() Method

:point_right: This method allows us to *remove* any number of *consecutive elements* from *anywhere* in an array and/or *add* new elements in place. 
:point_right: *Array.splice()* can take up to three parameters.
:point_right: We can use this method multiple times in a single code snippet , step by step. With each execution , the values of the indices change.

The basic syntax are:

```js
splice(start)
```
or,

```js
splice(start, deleteCount)
```
or,

```js
splice(start, deleteCount, item1, item2, itemN)
```
Let's know about these parameters and what they mean.

#### Parameters of Array.splice()

`start`

:small_orange_diamond: splice()'s *first parameter* represents the *index* on the array from which to *begin removing elements*.
:small_orange_diamond: If greater than the length of the array, `start` will be set to the *length of the array*. In this case, no element will be removed but the method will behave as an *adding function*, adding as many element as provided. 
:small_orange_diamond: splice() can also take *negative integers* as parameter. If negative, it will begin that many elements from the *end of the array*. In this case, -1 means -n , that is the index of the *nth last element*, and is therefore equivalent to the index of *array.length - n*. 

`deleteCount`

:small_orange_diamond: The *second parameter* indicates the number of elements to be *removed* or *replaced*.
:small_orange_diamond: It indicates the number of elements in the array to *remove* from `start`. 
:small_orange_diamond: If `deleteCount` is *omitted* or is *equal to or greater than* the number of elements left in the array, starting at `start`, then all the elements from `start` to the end of the array will be *eliminated*. 
:small_orange_diamond: If `deleteCount` is 0 or *negative*, no elements will be *removed*.

`item1, item2, ...., itemN`

:small_orange_diamond: The *third parameter* of splice() is *optional* and *only* used when we want to *add* elements to the array, beginning from the `start`.
:small_orange_diamond: If no element is *specified*, splice() will only *remove* elements from the array. 

Let's move on to some *examples* to understand this concept better. We need to always remember that index of an array starts at 0.

####:small_blue_diamond: Example 1: Remove 2 elements starting from index 2 and insert two new elements.

```js
let flowers = ["rose", "orchid", "marigold", "sunflower", "belly"];
let removed = flowers.splice(2, 2);

console.log(flowers); //output: [ 'rose', 'orchid', 'belly' ]
console.log(removed); //output: [ 'marigold', 'sunflower' ]
```
In this example, `start` is the index 2 and `deleteCount` is also 2 that means, splice() will start removing elements from index 2 and remove the values of index 2 and 3.

We can see the same example and insert two new elements *in place* of the removed elements :point_down:

```js
let flowers = ["rose", "orchid", "marigold", "sunflower", "belly"];
let removed = flowers.splice(2, 2, "almonda", "rosemary");

console.log(flowers); 
//output: [ 'rose', 'orchid', 'almonda', 'rosemary', 'belly' ]
console.log(removed); //output: [ 'marigold', 'sunflower' ]
```
Here, value of index 2 and 3 are removed and *in place* of them two new values are added.

####:small_blue_diamond: Example 2: Remove elements using splice() multiple times

```js
let flowers = [
  "rose",
  "orchid",
  "marigold",
  "sunflower",
  "belly",
  "almonda",
  "rosemary",
  "hibiscus",
];
let removed = flowers.splice(2,1);

console.log(removed); // [ 'marigold' ]
console.log(flowers); 
// ['rose', 'orchid', 'sunflower', 'belly', 'almonda', 'rosemary', 'hibiscus' ]

let removeAgain = flowers.splice(5,2); 
console.log(removeAgain); //[ 'rosemary', 'hibiscus' ]
console.log(flowers); 
// [ 'rose', 'orchid', 'sunflower', 'belly', 'almonda' ]

let include = flowers.splice(2,1,"tulip");
console.log(include); //[ 'sunflower' ]
console.log(flowers); 
//[ 'rose', 'orchid', 'tulip', 'belly', 'almonda' ]
```
In the *example* at first *marigold* is removed from *index 2*.
Now, the modified array holds *rosemary* and *hibiscus* at index 5 and 6. So, removed them using *splice(5,2). Lastly, "sunflower" has been replaced by "tulip". 
In the process of changing the original array, with the first execution, the value of the indices has been changed and depending on that we executed the next steps. 

####:small_blue_diamond: Example 3: Remove 0 (zero) elements before index 3, and insert 1 new element.

```js
let flowers = ["rose", "orchid", "marigold", "sunflower", "belly"];
let removed = flowers.splice(3, 0, "almonda");

console.log(flowers); 
//output: [ 'rose', 'orchid', 'marigold', 'almonda', 'sunflower', 'belly' ]
console.log(removed); //output: []
```

Here, `deleteCount` is 0 so nothing is removed but a new element is *added* to the array at index 3 as the *first parameter* of splice() is 3. 

####:small_blue_diamond: Example 4: Remove elements from index 0 and insert elements/nothing

```js
let birds = ["crow", "pigeon", "parrot"];
let removed = birds.splice(0, 2, "macaw", "peacock", "lovebird");

console.log(birds);
//output: [ 'macaw', 'peacock', 'lovebird', 'parrot' ]
console.log(removed); //output: [ 'crow', 'pigeon' ]
```
Let's see what happens if we take the *same* array and *remove* all the elements and *insert* nothing.

```js
let birds = ["crow", "pigeon", "parrot"];
let removed = birds.splice(0, 3) ;

console.log(instruments); //output: []
console.log(removed); //output: [ 'crow', 'pigeon', 'parrot' ]
```
In the above example, there were only 3 values and we *removed* 3 items from index 0, so the *output* shows an empty array.

####:small_blue_diamond: Example 5: Remove elements from index -n

```js
let colours = ['blue','black','red','pink','yellow','grey'];
let removed = colours.splice(-3, 2);

console.log(colours); //output: [ 'blue', 'black', 'red', 'grey' ]
console.log(removed); //output: [ 'pink', 'yellow' ]
```
In this case, `start` is -3 which indicates the *3rd last element* of the array and `deleteCount` is 2 which means the *splice()* method will remove 2 elements from the 3rd last element and the other values will be same as before. 

Let's add some new values to the array.

```js
let colours = ['blue','black','red','grey'];
let removed = colours.splice(-2, 1,'pink','purple');

console.log(colours); 
//output: [ 'blue', 'black', 'pink', 'purple', 'grey' ]
console.log(removed); //output: [ 'red' ]
```
Here, `start` is -2 which indicates the *2nd last element* of the array and `deleteCount` is 1 which means the *splice()* method will remove 1 element from the 2nd last element and *add* two new values starting from *index -2*.

####:small_blue_diamond: Example 6: Remove all elements, no deleteCount, no new insertion

Remove all elements starting from index 4 :point_down:

```js
let music = ['guitar','drums','violin','piano','tambourine','flute'];
let removed = music.splice(4);

console.log(music); 
//output: [ 'guitar', 'drums', 'violin', 'piano' ]
console.log(removed); //output: [ 'tambourine', 'flute' ]
```

Remove all elements starting from index -4 :point_down:

```js
let music = ['guitar','drums','violin','piano','tambourine','flute'];
let removed = music.splice(-4);

console.log(music); 
//output: [ 'guitar', 'drums' ]
console.log(removed); //output: [ 'violin', 'piano', 'tambourine', 'flute' ]
```

At this point, we have known enough of how to *modify* an array by adding and removing items. But there is another way which we can use to *access part of an array without modifying it*. That concept is known as **Array.slice()**

### Array.slice() Method

:point_right: Rather than modifying an array, `Array.slice()` copies or extracts a given number of elements to a new array, leaving the *original array* unmodified.
:point_right: It returns a shallow copy of elements from the original array. Elements of the original array are copied into the returned array.
:point_right: It can take only *two parameters* and both of them are *optional*

The basic syntax are: 
`slice()`
or
`slice(start)`
or
`slice(start,end)`

#### Parameters of Array.slice()

`start`

:small_orange_diamond: `start` indicates the *index* at which to *start extraction*
:small_orange_diamond: Index can be *negative*, indicating an *offset* from the *end* of the sequence.
:small_orange_diamond: The process generally starts extracting from index 0 if `start` is undefined.
:small_orange_diamond: If `start` is greater than the index range of the sequence, an empty array is returned. 

`end`

:small_orange_diamond: `end` indicates index *before which to end extraction*.
:small_orange_diamond: `slice()` extracts *up to* but not including *end*. For *example*, slice(1,4) starts extracting from index 1 through index 3. (elements indexed 1, 2, and 3 will be copied). 
:small_orange_diamond: A negative indexing can be used. For *example*, slice(2,-1) extracts the third element through the second-to-last element in the sequence. 
:small_orange_diamond: `slice()` extracts through the end of the sequence (array.length), if there is no `end` specified.
:small_orange_diamond: If `end` is greater than the *length* of the sequence, `slice()` extracts through to the end of the sequence (array.length). 

A few examples will clear the concept more. 


####:small_blue_diamond: Example 1: Return a Copy of the Original Array

```js
let music = ['guitar','drums','violin','piano','tambourine','flute'];
let extracted = music.slice();

console.log(music); 
//output: [ 'guitar', 'drums', 'violin', 'piano', 'tambourine', 'flute' ]
console.log(extracted); 
//output: [ 'guitar', 'drums', 'violin', 'piano', 'tambourine', 'flute' ]
```
As *no parameter* is passed within `slice()`, it returns the whole array unchanged. 

####:small_blue_diamond: Example 2: Return a Part of the Existing Array, only using one parameter

```js
let fruits = ['mango', 'apple', 'orange', 'grape', 'lemon', 'banana', 'kiwi'];
let extracted = fruits.slice(3);

console.log(fruits); 
//output: ['mango', 'apple', 'orange', 'grape', 'lemon', 'banana', 'kiwi']
console.log(extracted); 
//output: [ 'grape', 'lemon', 'banana', 'kiwi' ]
```
In the above *example*, the *original array* is unchanged after *slice()* being called upon it but the new array *extracted* holds the copies of the values starting from *index 3*. As no `end` is specified, `slice()` extracted all the value through *array.length*

####:small_blue_diamond: Example 3: Return a Part of the Existing Array, using both parameters

```js
let fruits = ['mango', 'apple', 'orange', 'grape', 'lemon', 'banana', 'kiwi'];
let extracted = fruits.slice(2,5);

console.log(fruits); 
//output: ['mango', 'apple', 'orange', 'grape', 'lemon', 'banana', 'kiwi']
console.log(extracted); 
//output: [ 'orange', 'grape', 'lemon' ]
```
This *example* shows, the *original array* is unchanged after *slice()* being called upon it but the new array *extracted* holds the copies of the values starting from *index 2* up to *index 5* but not including the value of *index 5*. The *extracted* array holds the copies of values indexed at 2, 3 and 4.

### Summarizing Array.splice() vs Array.slice() 

|Array.splice()|Array.slice()|
| --------- | --------- | 
|The `splice()` method returns the removed item(s) in an array.|The `slice()` method returns the selected element(s) in an array, as a new array object.|
|This method *changes* the original array.|This method *doesn’t change* the original array.| 
|It *does not create any copy* of the existing array, rather *modifies* it.| It just *creates a shallow copy* of the existing array *without* doing any *modification* to it.|
|Can take *three* parameters|Can take *two* parameters|
|When we write splice(2,4), it starts removing values from index 2 and remove 4 elements, *including* the value of index 4 (removed items will be indexed at 2,3,4 & 5)| When we write slice(2,4), it extracts values of index 2 up to index 4, *excluding* the value of index 4 (removed items will be indexed at 2 & 3)|
|In this method, the third parameter gives the *option to add* one or more new items to the existing array|There is no such *adding option* in this method|

In the end , I'll give only one problem to solve to my readers. Let's see how you solve this.

:black_square_button: Use `splice()` to remove *"USA"* first and then *from "Japan" to "Canada"*. Insert *"Bhutan"* in place of *"UK"*. Use `slice()` to keep a *copy* of the original array.

```js
let countries = [
  "Bangladesh","India","Nepal","USA",
  "UK","Germany","Japan","Spain","Canada"
];
```
Expected Output: 
```
[ 'Bangladesh', 'India', 'Nepal', 'Bhutan', 'Germany' ]
```
Readers can post their solutions in the discussion part.