Most of the array gymnastics we do in JavaScript boils down to a handful of patterns that show up in almost every codebase — deduping a list pulled from an API, flattening nested results, chunking data for pagination. Here are seven one-liners we reach for constantly, with a quick note on when each one actually earns its place.
1. Dedupe an array. Wrapping an array in a Set strips duplicates because a Set only stores unique values, and spreading it back into an array gives you a plain array again. Useful whenever you have merged two lists of IDs or tags and do not want repeats.
const ids = [1, 2, 2, 3, 3, 3];
const unique = [...new Set(ids)];
// [1, 2, 3]
2. Flatten nested arrays. .flat(Infinity) collapses arrays of arbitrary nesting depth into one flat array in a single call, which beats writing a recursive flattening function by hand. Reach for it after a series of .map() calls that each return sub-arrays, or when normalizing tree-shaped API responses.
const nested = [1, [2, 3], [4, [5, 6]]];
const flat = nested.flat(Infinity);
// [1, 2, 3, 4, 5, 6]
3. Sum a list of numbers. .reduce() is the general-purpose tool for collapsing an array into a single value, and summing is the simplest case — pass 0 as the initial accumulator so an empty array still returns 0 instead of undefined.
const prices = [19.99, 5.5, 12];
const total = prices.reduce((sum, price) => sum + price, 0);
4. Chunk an array into fixed-size groups. Array.from() with a length-based iterator builds the chunked array in one expression instead of a manual loop with push(). Handy for batching API requests or paginating a list client-side.
const chunk = (arr, size) =>
Array.from({ length: Math.ceil(arr.length / size) }, (_, i) =>
arr.slice(i * size, i * size + size)
);
chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]]
5. Find the intersection or difference of two arrays. .filter() combined with .includes() gives you either set operation depending on whether you negate the check. For large arrays, swap .includes() for a Set lookup to avoid a quadratic scan.
const a = [1, 2, 3, 4];
const b = [3, 4, 5, 6];
const intersection = a.filter(x => b.includes(x)); // [3, 4]
const difference = a.filter(x => !b.includes(x)); // [1, 2]
6. Group items by a key. Object.groupBy() turns a flat array into an object keyed by whatever your callback returns, replacing the reduce-based grouping helper most of us used to hand-roll.
const orders = [
{ id: 1, status: 'open' },
{ id: 2, status: 'closed' },
{ id: 3, status: 'open' },
];
const byStatus = Object.groupBy(orders, order => order.status);
// { open: [{...}, {...}], closed: [{...}] }
7. Grab the last element without arr.length - 1. .at(-1) accepts negative indices, so it reads cleanly as "give me the last item" (or arr.at(-2) for second-to-last) without a separate length lookup.
const queue = ['a', 'b', 'c'];
const last = queue.at(-1); // 'c'
- Dedupe with [...new Set(arr)]
- Flatten with .flat(Infinity)
- Sum with .reduce()
- Chunk with Array.from()
- Intersect/diff with .filter() + .includes()
- Group with Object.groupBy()
- Last item with .at(-1)
Object.groupBy() is newer than the rest of this list — if you need to support an older browser or Node runtime, fall back to a reduce that pushes each item into an array keyed by your grouping function.
Wrapping Up
None of these are exotic — that is the point. They read fast, they are hard to get wrong, and swapping them in for hand-rolled loops usually makes a diff easier to review.