Array Manipulation Patterns
array-manipulation-patterns
Data Structures
Arrays & Strings
Reading `arr[1000000]` takes the same amount of time as reading `arr[0]`, because an array's contiguous memory layout lets the runtime compute the address of any element with a single multiplication. That single property is what makes **Arrays & Strings** the workhorse data structure of nearly every program you will ever write. This lesson walks through array declaration and indexing in JavaScript and Python, the cost of inserts and deletes that force shifting, slicing and subarray patterns, and the basic string operations every interview problem assumes you know. You will also see why strings behave as immutable character arrays in both languages and what that means for performance when you build strings inside a loop. In **How to Read Code (JS & Python)**, you practiced tracing programs line by line; that habit is exactly how you will reason about loop indices and slice boundaries here. **Big-O Notation (Upper Bound)** gave you the language to express scaling behavior, and arrays are where you will first see `O(1)` access sit next to `O(n)` insertion in the same data structure. Once array fundamentals are second nature, **Matrix/Grid Fundamentals** extends the same indexing intuition into two dimensions, where row and column traversal patterns power BFS, DFS, and dynamic programming on grids.
Not Started
0%
Algorithms
Iteration Patterns on Arrays/Strings
Look at almost any solved interview problem and you will see the same six or seven shapes of `for` loop reappearing: a single sweep that finds a max, a nested pair that compares every element to every other, a single sweep that fills a frequency table. Before you can recognize when two pointers or sliding window will help, you have to recognize these primitive shapes on sight. **Iteration Patterns on Arrays/Strings** catalogs those shapes. You will work through single-pass templates (running sum, find max/min, counting), nested-loop templates that consider all pairs in `O(n^2)` time, frequency counting with a hash map, early termination with `break`, sentinel values, and the choice between in-place modification and building a new array. Classic transformations like reverse, rotate, and partition appear as named patterns rather than puzzles solved from scratch each time. In **Arrays & Strings**, you saw that arrays give you constant-time indexed access and contiguous memory. This lesson turns that storage model into actual movement: how an index walks across an array, what it costs, and when one walk is enough. Next you will use these patterns directly in **Prefix Sum & Difference Array**, where a single preprocessing pass replaces many later range-sum loops.
Not Started
0%
Practice Problems
Rotate Array
Rotate an array to the right by k steps in-place using the reverse technique for O(1) extra space.
Code Snippets
Chunk an Array into Fixed Sizes
Splitting an array into fixed-size groups is a recurring need for pagination, batch API calls, and grid layouts. This snippet covers a one-line slice loop, a generator variant for streaming large inputs, and the edge cases (size <= 0, non-integer size, non-multiple lengths) that bite production code. Drop it in as a tiny utility and stop reaching for lodash for one helper.
Flatten a Nested Array
Flattening a nested array is a one-line job most of the time, but pre-built `Array#flat` is shallow by default and the depth parameter has surprises. This snippet starts with the modern built-in, adds a recursive deep-flatten that works in any environment, and ends with the iterative stack version that avoids stack-overflow on pathological inputs. Three flavours, one mental model.
Shuffle an Array (Fisher-Yates)
The naive `array.sort(() => Math.random() - 0.5)` looks fine until you measure it: the distribution is heavily biased and some pairs swap with much higher probability than others. The Fisher-Yates shuffle is the standard correct answer in O(n) time with uniform output. This snippet shows the in-place version, a non-mutating wrapper, and an empirical demo of why the popular `sort`-based trick is biased.
Group an Array by a Key
Grouping records by a derived key is one of the most common data-shaping tasks in JavaScript: bucketing users by role, orders by status, logs by date. This snippet shows a portable `Map`-based helper, a plain-object variant, and the modern `Object.groupBy` API that landed in Node 22 and recent browsers. It also covers the multi-key composite-key trick for grouping by tuples like `[city, role]`.
Partition an Array by a Predicate
Calling `array.filter(p)` and `array.filter((x) => !p(x))` works but walks the input twice and runs the predicate twice per element, which is wasteful and (for non-pure predicates) plain wrong. A single-pass `partition` returns the matched and unmatched buckets in one go. This snippet covers a clean fold-based implementation, an N-way `partitionBy` for multi-class splits, and a streaming variant that lazily partitions an iterable without materialising the full input.
Zip Multiple Arrays
Python users miss `zip(a, b)` and the Lodash crowd reaches for `_.zip`, but JavaScript can do this cleanly with one helper. This snippet covers the basic two-array zip, an N-array variadic version, the unzip inverse, and a `zipWith` that lets you fold pairs into custom shapes (records, objects, weighted sums). It also clarifies the truncate-to-shortest vs. fill-with-undefined trade-off.
Flatten a Nested Data Object
Analytics events, form payloads, and config files often arrive as deeply nested objects, but databases, query strings, and CSV exporters want a flat key-value map. This snippet builds a recursive flattener that produces dot-path keys, extends it to handle arrays with bracket notation, and adds the inverse `unflatten` so the round-trip is lossless. Drop it next to your event tracker or form serializer.
Insert, Update, Remove Items by Index
Index-based mutations are where most array bugs come from: `splice` mutates in place and is easy to misuse, while `slice` plus spread gives you a copy without mutating the input. This snippet contrasts the mutable and immutable forms for the four common index operations (remove by index, update by index, insert at index, remove all matching a predicate). Keep mutation explicit at the call site so reviewers know whether the original array survives.
Merge and Sort Two Arrays
Merging two arrays of numbers is the kind of task whose right answer depends entirely on whether the inputs are already sorted. This snippet shows three patterns: a simple concat-then-sort for small or unsorted inputs, the classic two-pointer linear merge for already-sorted inputs, and an in-place variant that fills a preallocated buffer for hot paths. Pick by input shape and size, not by habit.
Reversing an Array (Iterative, Recursive, Copy)
Reversing an array is a one-liner if you do not mind mutating the input, and a slightly different one-liner if you do. This snippet covers the built-in `reverse()` mutating call alongside the immutable `toReversed()` and spread alternatives, the two-pointer in-place swap that interviewers ask about, and a recursive form for the recursion lesson. Production code should pick one of the first-accordion forms; the others are for understanding.
Question Banks
JavaScript Array Method Output Traces
Six traces drilling on in-place vs returning array methods: `reverse`, sparse arrays, `indexOf`, `filter(Boolean)`, default lexicographic `sort`, and `copyWithin`.
Array Cross-Reference and Lookup Challenges
Six lookup-and-filter drills: id-to-id matching with Sets, random sampling without duplicates, valid-only filtering, numeric-only extraction, value-by-row matching, and rest-parameter multipliers.
Tree-from-Flat-Array Challenges
Three drills on shape conversion: building a nested tree from a flat list (numeric ids), building from a nested list with string parents, and assembling a graph adjacency list.
JavaScript Take-Out-and-Rest Array: Two Approaches Quiz
Two seeded approaches to build a map of each-element-to-the-rest (reduce + filter and forEach + filter), plus two companions on slice + concat and a complexity discussion.
JavaScript Group Students by ID: Two Approaches Quiz
Two seeded approaches to group an array of student records by id (reduce + dict and the `in` operator), plus two companions on Map and Object.groupBy.
JavaScript Largest Difference Without Sort: Two Approaches Quiz
Two seeded approaches to compute the largest pairwise difference in an array without sorting (single-pass min/max and the brute-force nested loop), plus two companions on prefix tracking and a negative-numbers twist.
JavaScript Top-N Numbers (Preserving Order): Two Approaches Quiz
Return the N largest numbers from an array while keeping their original order, two ways (sort-and-filter-back and threshold partition), plus two companions on ties and a heap-style streaming variant.
JavaScript Min/Max Leave-One-Out Sum: Three Approaches Quiz
Compute the smallest and largest "drop one and sum the rest" totals three ways (sort + slice, total-sum minus extremum, single-pass min/max tracker), plus two companions on streaming inputs and a top-K leave-out generalisation.
JavaScript Top-N Numbers: Two Approaches Quiz
Return the N largest numbers from an array (order-not-required), two ways (sort + slice and one-pass min-tracking buffer), plus two companions on heap-style updates and tie-aware quickselect.
JavaScript Array Occurrences Count: Two Approaches Quiz
Tally how many times each value appears in an array, two ways (reduce + dict and Map-based counter), plus two companions on Object.create(null) safety and case-insensitive string tallies.
JavaScript Grouped Scores Filter: Two Approaches Quiz
Filter a grouped scores object so each row keeps only requested keys, solved two ways (Object.entries + map and a for-in loop), plus companions on Map output and key-rename mapping.
JavaScript Missing Numbers Finder: Two Approaches Quiz
Find missing integers between the min and max of an array, two ways (sort + gap-walk and Set diff over min..max), plus companions on the consecutive-1..n case and detecting duplicates.
JavaScript Array Pair Extraction: Two Approaches Quiz
Split an array into consecutive pairs (with a trailing single when the length is odd), two ways (reduce with odd-index push and a stepped slice loop), plus companions on a generic chunk size and a lazy generator variant.
JavaScript Largest Difference in Array: Three Approaches Quiz
Three seeded ways to compute the maximum pairwise gap in an integer array (sort and subtract ends, reduce with Math.max and Math.min, single-pass tracker), plus two companions on edge cases and complexity.
JavaScript find vs filter for Student Lookup Quiz
Two seeded approaches to look up students by name: `find` returns the first match, `filter` returns every match. Two companions cover return-type pitfalls and short-circuit semantics.
JavaScript Square and Join Digits: Two Approaches Quiz
Two seeded ways to square each digit of an integer and concatenate the results (string split with map and join, plus a while-loop modulo extraction), with two companions on negative numbers and on returning a string.
JavaScript Group By ID with Average Score: Two Approaches Quiz
Two seeded ways to group records by id and compute each group's average (bucket-then-divide vs running sum + count), plus two companions on min/max per group and on memory trade-offs at scale.
Community
Sliding Window Technique
What sliding window actually optimises (state reuse, not just same-direction pointers), the fixed vs variable templates, four canonical problems, and when the technique is the wrong tool.
Monotonic Stack: The Pattern Everyone Skips
The next-greater-element trick that turns O(n^2) scans into O(n). Daily temperatures, largest rectangle in histogram, and trapping rain water, all from the same shape.
Two Pointers Technique
The three sub-patterns (opposite ends, same direction, fast-slow), the canonical problems each one solves, and why recognizing the shape is the entire skill.
