Remove An Element From A Slice In
Fast recall
Quick revision
Core answer
Whether you understand Slice Tricks beyond memorized syntax.
Giving a definition without explaining a practical trade-off.
Connect the concept to a small production example and state its complexity or failure mode.
Interview-ready guide
Interview answer
Two idioms, two contracts. The append-shift preserves order and costs O(n-i) — everything after the removed element copies one slot left:
s := []int{1, 2, 3, 4}
s = append(s[:1], s[2:]...) // remove index 1
// s is now [1 3 4]The mechanics: s[2:] is the tail [3 4]; append copies it onto s starting at index 1; the result's header is reassigned to s. The elements move — that's the O(n) price of keeping order.
The swap-delete trades order for O(1) — copy the last element into the hole, shrink by one:
s := []int{1, 2, 3, 4}
s[1] = s[len(s)-1] // [1 4 3 4]
s = s[:len(s)-1] // [1 4 3]No shifting, no copy loop — one store and one reslice. This is the standard trick for removing from unordered collections (task queues, membership sets, draw-pools) where position means nothing. The interview answer that stands out is knowing BOTH and naming the invariant that decides: is order part of this collection's meaning?
Remove An Element From A Slice In
Direct Answer
Order preserved: s = append(s[:i], s[i+1:]...) — shifts the tail left. Order destroyed: s[i] = s[len(s)-1]; s = s[:len(s)-1] — O(1) swap-delete.
Deep Dive & Architecture
Both idioms are append/copy mechanics, and seeing them as such removes the memorization. The ordered remove, append(s[:i], s[i+1:]...), is a left-shift: the tail s[i+1:] is copied onto s starting at i — same backing array, elements slide down one, the header's len drops by one via the returned append result.
Executed: [1 2 3 4] remove index 1 → append([1], [3 4]...) → [1 3 4].
The swap-delete, s[i] = s[len(s)-1]; s = s[:len(s)-1], never moves the tail: it copies the LAST element into the hole (one store) and shrinks the window (one reslice). Executed: [1 2 3 4] delete index 1 → s[1]=4 → [1 4 3 4] → s[:3] → [1 4 3].
The invariants each preserves explain when to use which:
- Order matters (display, pagination, priority queues backed by slices): append-shift — O(n) is the price of the contract.
- Order doesn't (membership sets, work queues, LRU scratch): swap-delete — O(1) with the honest cost that position is meaningless.
One subtlety worth knowing: remove-while-ranging. The ranged loop's snapshot means deleting the CURRENT index inside range needs a manual index (for i := 0; i < len(s); i++ with the decrement after removal) — but the idiomatic form is filter-into-new because it states intent. The shift/swap tricks are for spot-removal; the filter is for sweeps.
Common Mistakes & Pitfalls
Giving a definition without explaining a practical trade-off.
Check your understanding
Answer these without looking back at the article.
- When would you use Slice Tricks in a real project?
- How would you compare Slice Tricks with an alternative?
- What is a common mistake when using Slice Tricks?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.