Basic Array Operations (Insert, Delete, Access)
Understanding how to efficiently perform basic operations like accessing, inserting, and deleting elements in an array is crucial. While JavaScript provides convenient built-in methods, it's essential to grasp their underlying behavior and time complexity. This knowledge will guide you in choosing the right methods for optimal performance.
1. Accessing Elements (Read)
Accessing an element means retrieving the value at a specific index.
-
How it works: You use bracket notation (
array[index]) to directly jump to the memory location of the desired element. -
Time Complexity: O(1) - Constant Time
- This is the most efficient array operation. Regardless of how large the array is (n), accessing
array[0]takes the same amount of time as accessingarray[n-1]. This is because arrays (conceptually) store elements in contiguous memory, allowing direct calculation of an element's address.
- This is the most efficient array operation. Regardless of how large the array is (n), accessing
-
How it works: You use bracket notation (
array[index]) to directly jump to the memory location of the desired element. -
Time Complexity: O(1) - Constant Time
- This is the most efficient array operation. Regardless of how large the array is (n), accessing
array[0]takes the same amount of time as accessingarray[n-1]. This is because arrays (conceptually) store elements in contiguous memory, allowing direct calculation of an element's address.
- This is the most efficient array operation. Regardless of how large the array is (n), accessing
Example:
const colors = ['red', 'green', 'blue', 'yellow'];
console.log(colors[0]); // Accesses the first element: 'red' (O(1))
console.log(colors[2]); // Accesses the third element: 'blue' (O(1))
2. Insertion Operations
Inserting an element means adding a new item to the array. Where you insert it significantly impacts performance.
2.1. Insertion at the End (push())
-
How it works:
push()adds one or more elements to the end of an array. JavaScript arrays are dynamic, so they automatically handle resizing the underlying memory if needed. -
Time Complexity: O(1) - Constant Time (Amortized)
- Most of the time,
push()is incredibly fast. When the array has enough allocated space, adding an element is just placing it in the next available spot. - Occasionally, when the array runs out of pre-allocated space, it needs to be resized (a new, larger array is created, and all existing elements are copied over). This resizing operation is O(n). However, these expensive resizes happen infrequently and are spread out over many
push()operations, making the average (amortized) time complexity O(1).
- Most of the time,
Example:
const fruits = ['apple', 'banana'];
fruits.push('cherry'); // Adds 'cherry' to the end
console.log(fruits); // Output: ['apple', 'banana', 'cherry']
2.2. Insertion at the Beginning (unshift())
-
How it works:
unshift()adds one or more elements to the beginning of an array. To do this, all existing elements must be shifted one position to the right to make space for the new element(s) at index0. -
Time Complexity: O(n) - Linear Time
- Because every existing element needs to be re-indexed, the time taken grows linearly with the size of the array (n).
-
How it works:
unshift()adds one or more elements to the beginning of an array. To do this, all existing elements must be shifted one position to the right to make space for the new element(s) at index0. -
Time Complexity: O(n) - Linear Time
- Because every existing element needs to be re-indexed, the time taken grows linearly with the size of the array (n).
Example:
const animals = ['dog', 'cat'];
animals.unshift('bird'); // Adds 'bird' to the beginning
console.log(animals); // Output: ['bird', 'dog', 'cat']
2.3. Insertion at a Specific Index (splice())
-
How it works:
splice()is a powerful method that can add, remove, or replace elements at any position. To insert elements,splice()shifts existing elements to the right to accommodate the new ones. -
Time Complexity: O(n) - Linear Time
- Similar to
unshift(), inserting in the middle requires shifting approximately half of the array's elements. The number of shifts depends on the insertion point, but in the worst case, it's proportional to n.
- Similar to
-
How it works:
splice()is a powerful method that can add, remove, or replace elements at any position. To insert elements,splice()shifts existing elements to the right to accommodate the new ones. -
Time Complexity: O(n) - Linear Time
- Similar to
unshift(), inserting in the middle requires shifting approximately half of the array's elements. The number of shifts depends on the insertion point, but in the worst case, it's proportional to n.
- Similar to
Example:
const numbers = [1, 2, 5, 6];
// splice(startIndex, deleteCount, item1, item2, ...)
numbers.splice(2, 0, 3, 4); // At index 2, delete 0 elements, then add 3 and 4
console.log(numbers); // Output: [1, 2, 3, 4, 5, 6]
2.4. Manual Insertion at a Specific Index (Shifting Elements by Hand)
-
Why? To understand what
splice()does under the hood and to practice index arithmetic, loop control, and edge-case handling. -
Time Complexity: O(n) - Linear Time
- You still must shift every element after the insertion point.
How it works (pseudocode):
- Clamp the target index to the valid range
[0 … arr.length]. - Grow the array’s length by one (creates an “empty” slot at the end).
- Loop backwards from the new last index down to
index + 1, assigningarr[i] = arr[i - 1]. - Write the new element at
arr[index].
/**
* insertAt(arr, element, index)
* — Manual insertion without splice/push/unshift
* Time: O(n)
*/
function insertAt(arr, element, index) {
// 1. Clamp index
if (index <= 0) {
index = 0;
} else if (index >= arr.length) {
index = arr.length;
}
// 2. Grow array
arr.length++;
// 3. Shift right
for (let i = arr.length - 1; i > index; i--) {
arr[i] = arr[i - 1];
}
// 4. Insert element
arr[index] = element;
return arr;
}
Example Walk-through:
| Step | Array | Action |
|---|---|---|
| 0 | ['a','b','c','d'] | initial |
| 1 | ['a','b','c','d', ] | grow (length→5) |
| 2 | ['a','b','c','d','d'] | shift i=4←3 |
| 3 | ['a','b','c','c','d'] | shift i=3←2 |
| 4 | ['a','b','b','c','d'] | shift i=2←1 |
| 5 | ['a','b','X','c','d'] | insert at index 2 |
2.4. Manual Insertion at a Specific Index (Shifting Elements by Hand)
-
Why? To understand what
splice()does under the hood and to practice index arithmetic, loop control, and edge-case handling. -
Time Complexity: O(n) - Linear Time
- You still must shift every element after the insertion point.
How it works (pseudocode):
- Clamp the target index to the valid range
[0 … arr.length]. - Grow the array’s length by one (creates an “empty” slot at the end).
- Loop backwards from the new last index down to
index + 1, assigningarr[i] = arr[i - 1]. - Write the new element at
arr[index].
/**
* insertAt(arr, element, index)
* — Manual insertion without splice/push/unshift
* Time: O(n)
*/
function insertAt(arr, element, index) {
// 1. Clamp index
if (index <= 0) {
index = 0;
} else if (index >= arr.length) {
index = arr.length;
}
// 2. Grow array
arr.length++;
// 3. Shift right
for (let i = arr.length - 1; i > index; i--) {
arr[i] = arr[i - 1];
}
// 4. Insert element
arr[index] = element;
return arr;
}
Example Walk-through:
| Step | Array | Action |
|---|---|---|
| 0 | ['a','b','c','d'] | initial |
| 1 | ['a','b','c','d', ] | grow (length→5) |
| 2 | ['a','b','c','d','d'] | shift i=4←3 |
| 3 | ['a','b','c','c','d'] | shift i=3←2 |
| 4 | ['a','b','b','c','d'] | shift i=2←1 |
| 5 | ['a','b','X','c','d'] | insert at index 2 |
3. Deletion Operations
Deleting an element means removing an item from the array. Similar to insertion, the location of deletion affects performance.
3.1. Deletion from the End (pop())
-
How it works:
pop()removes the last element from an array. -
Time Complexity: O(1) - Constant Time
- This is efficient because no other elements need to be re-indexed or shifted. The pointer to the end of the array simply moves inward.
-
How it works:
pop()removes the last element from an array. -
Time Complexity: O(1) - Constant Time
- This is efficient because no other elements need to be re-indexed or shifted. The pointer to the end of the array simply moves inward.
Example:
const items = ['pen', 'notebook', 'eraser'];
const removedItem = items.pop(); // Removes 'eraser'
console.log(items); // Output: ['pen', 'notebook']
console.log(removedItem); // Output: 'eraser'
3.2. Deletion from the Beginning (shift())
-
How it works:
shift()removes the first element from an array. To do this, all remaining elements must be shifted one position to the left to fill the gap created by the removed element. -
Time Complexity: O(n) - Linear Time
- Because every remaining element needs to be re-indexed, the time taken grows linearly with the size of the array (n).
-
How it works:
shift()removes the first element from an array. To do this, all remaining elements must be shifted one position to the left to fill the gap created by the removed element. -
Time Complexity: O(n) - Linear Time
- Because every remaining element needs to be re-indexed, the time taken grows linearly with the size of the array (n).
Example:
const guests = ['Alice', 'Bob', 'Charlie'];
const removedGuest = guests.shift(); // Removes 'Alice'
console.log(guests); // Output: ['Bob', 'Charlie']
console.log(removedGuest); // Output: 'Alice'
3.3. Deletion from a Specific Index (splice())
-
How it works:
splice()can also remove elements from any position. When elements are removed, subsequent elements are shifted to the left to fill the gap. -
Time Complexity: O(n) - Linear Time
- Removing from the middle requires shifting elements. The number of shifts depends on how many elements are after the deletion point, but in the worst case, it's proportional to n.
-
How it works:
splice()can also remove elements from any position. When elements are removed, subsequent elements are shifted to the left to fill the gap. -
Time Complexity: O(n) - Linear Time
- Removing from the middle requires shifting elements. The number of shifts depends on how many elements are after the deletion point, but in the worst case, it's proportional to n.
Example:
const letters = ['a', 'b', 'c', 'd', 'e'];
// splice(startIndex, deleteCount)
letters.splice(2, 1); // At index 2, delete 1 element ('c')
console.log(letters); // Output: ['a', 'b', 'd', 'e']
3.4. Manual Deletion at a Specific Index (Shifting Elements by Hand)
- Why? To see how
splice()really works under the hood, and to practice index arithmetic, loop control, and edge-case handling. - Time Complexity: O(n) — because every element after the removal point must shift one slot to the left.
How it works (pseudocode):
-
Bounds check: if
index < 0orindex ≥ arr.length, returnundefined. -
Store the element to remove:
removed = arr[index]. -
Shift all elements to the left:
for (let i = index; i < arr.length - 1; i++) { arr[i] = arr[i + 1]; } -
Trim the array’s length:
arr.length = arr.length - 1. -
Return the removed value.
Example Walk-through
| Step | Array | Action |
|---|---|---|
| 0 | ['a','b','c','d','e'] | initial |
| 1 | — | store removed = 'c' |
| 2 | ['a','b','d','d','e'] | shift i=2←3 |
| 3 | ['a','b','d','e','e'] | shift i=3←4 |
| 4 | — | shorten: length→4 |
| 5 | ['a','b','d','e'] | result, and return 'c' |
Then you simply follow with your “Challenge: Manual Array Deletion” prompt:
function removeFrom(arr, index) {
// implement manual deletion without splice/pop/shift…
}
Summary of Basic Array Operation Complexities
| Operation | Time Complexity | Description |
|---|---|---|
| Access (by index) | O(1) | Direct, fast lookup. |
Insert at End (push) | O(1) (Amortized) | Usually fast, occasional O(n) for resize. |
Delete from End (pop) | O(1) | Fast, no shifting required. |
Insert at Beginning (unshift) | O(n) | Requires shifting all existing elements. |
Delete from Beginning (shift) | O(n) | Requires shifting all remaining elements. |
Insert at Middle (splice) | O(n) | Requires shifting elements after the insertion point. |
| Manual Insert at Middle | O(n) | Same as splice but by-hand shifting to illustrate internal mechanics. |
Delete from Middle (splice) | O(n) | Requires shifting elements after the deletion point. |

