· tips  · 4 min read

Array Manipulation in a Single Line

Learn to transform arrays with concise, expressive one-liners using map, filter, reduce and related tools. Practical patterns: sum, unique elements, flattening, grouping, counting, and safe chaining.

Learn to transform arrays with concise, expressive one-liners using map, filter, reduce and related tools. Practical patterns: sum, unique elements, flattening, grouping, counting, and safe chaining.

Outcome: write clear, powerful array one-liners that solve common tasks - summing numbers, deduplicating, grouping, flattening - without verbose loops.

Why single-line array manipulations?

You want readable, expressive code. One-liners do more than save lines: they capture intent. A focused one-liner using map, filter, or reduce often communicates what you’re doing rather than how.

Below are practical patterns you can drop into real code. Each example is a single expression (not counting comments). I include short notes on readability and alternatives when appropriate.

Note: these examples use modern JavaScript (ES6+). For reference docs see MDN: map, filter, reduce, flat, flatMap.

Sum values - concise and clear

Sum numeric values in an array.

const sum = arr => arr.reduce((s, n) => s + n, 0);
// usage
sum([1, 2, 3, 4]); // 10

Why this works: reduce accumulates a running total. Start value 0 avoids surprises with empty arrays.

Sum of mapped properties

Add up a property across objects (e.g., total price):

const total = items => items.reduce((s, { price = 0 } = {}) => s + price, 0);
// usage
total([{ price: 10 }, { price: 5 }]); // 15

Using destructuring keeps the one-liner compact and safe (defaults prevent undefined addition).

Unique elements - using Set (fast and readable)

Turn an array into unique values preserving insertion order:

const unique = arr => [...new Set(arr)];
// usage
unique([1, 2, 2, 3, 1]); // [1, 2, 3]

Set is concise and typically the fastest approach for primitive values.

Unique elements - single-line reduce (no Set)

Sometimes you want full control over equality or wish to avoid Set:

const uniqueBy = (arr, fn = x => x) =>
  arr.reduce((u, x) => (u.some(y => fn(y) === fn(x)) ? u : [...u, x]), []);
// usage
uniqueBy([{ id: 1 }, { id: 2 }, { id: 1 }], o => o.id); // [{id:1},{id:2}]

This one-liner preserves the first occurrence by checking the accumulator with some.

Flatten nested arrays

Flatten one level (ES2019+):

const flatOne = arr => arr.flat();
// usage
flatOne([
  [1, 2],
  [3, 4],
]); // [1,2,3,4]

If flat isn’t available, use reduce + concat:

const flatOneAlt = arr => arr.reduce((r, a) => r.concat(a), []);

Flatten and map (flatMap)

Map then flatten in a single pass:

const words = ['hello world', 'foo bar'];
const tokens = words.flatMap(s => s.split(' '));
// tokens -> ['hello', 'world', 'foo', 'bar']

flatMap is often both faster and clearer than map(...).flat().

Group by (single-line reduce)

Group items by a key into an object:

const groupBy = (arr, keyFn) =>
  arr.reduce((acc, item) => ((acc[keyFn(item)] ||= []).push(item), acc), {});
// usage
groupBy([{ cat: 'a' }, { cat: 'b' }, { cat: 'a' }], x => x.cat);
// => { a: [{cat:'a'},{cat:'a'}], b: [{cat:'b'}] }

Notes: the (expr, acc) comma trick keeps it a single expression. ||= is concise but requires modern engines (ES2021).

If you prefer compatibility:

const groupByCompat = (arr, keyFn) =>
  arr.reduce((acc, item) => {
    const k = keyFn(item);
    acc[k] = acc[k] || [];
    acc[k].push(item);
    return acc;
  }, {});

Count occurrences (frequency map)

Count frequencies in one expression:

const counts = arr => arr.reduce((m, x) => ((m[x] = (m[x] || 0) + 1), m), {});
// usage
counts(['a', 'b', 'a']); // { a: 2, b: 1 }

If you prefer Map for non-string keys:

const countsMap = arr =>
  arr.reduce((m, x) => (m.set(x, (m.get(x) || 0) + 1), m), new Map());

Partitioning - split into two arrays by predicate

Produce [pass, fail] arrays:

const partition = (arr, pred) =>
  arr.reduce((r, x) => (r[pred(x) ? 0 : 1].push(x), r), [[], []]);
// usage
partition([1, 2, 3, 4], n => n % 2 === 0); // [[2,4], [1,3]]

Safe property pluck with chaining and fallback

Collect nested properties safely and remove undefined/null in one line:

const pluck = (arr, pathFn) => arr.map(pathFn).filter(x => x != null);
// usage
pluck([{ a: { b: 1 } }, {}], o => o.a?.b); // [1]

This uses optional chaining and removes falsy null/undefined values.

Complex transform: combine map+filter+reduce in one expression

A realistic pipeline: normalize numbers, remove invalid, sum.

const sumNormalized = arr =>
  arr
    .map(x => Number(x))
    .filter(n => Number.isFinite(n))
    .reduce((s, n) => s + n, 0);
// usage
sumNormalized(['1', '2', 'foo', 3]); // 6

It’s a readable linear pipeline: parse, validate, reduce.

One-liner tips for readability

  • Prefer named small helper functions (e.g., sum, groupBy) when reused.
  • Don’t cram too many operations into one line if it harms comprehension; short helper names rescue clarity.
  • Use comments above dense one-liners for intent.
  • Use modern syntax (flatMap, ?., ||=, destructuring) for clarity and brevity - but be mindful of runtime support.

Cheat sheet: patterns you’ll reuse

  • Sum: arr.reduce((s,n)=>s+n,0)
  • Unique (primitives): [...new Set(arr)]
  • Unique by property: arr.reduce((u,x)=>u.some(y=>y.id===x.id)?u:[...u,x],[])
  • Flatten: arr.flat() or arr.reduce((r,a)=>r.concat(a),[])
  • Flat map: arr.flatMap(fn)
  • Group: arr.reduce((a,x)=>(a[keyFn(x)] ||= []).push(x), a), {})
  • Count: arr.reduce((m,x)=>(m[x]=(m[x]||0)+1,m),{})
  • Partition: arr.reduce((r,x)=>(r[pred(x)?0:1].push(x),r),[[],[]])

When not to one-line

One-liners aren’t a goal - clarity is. If your expression uses nested side effects, multiple ternaries, or long arrow bodies, split it into named steps. The best one-liners read like a single clear sentence.

Further reading

Back to Blog

Related Posts

View All Posts »
Bitwise Swapping: A Deeper Dive into JavaScript's Oddities

Bitwise Swapping: A Deeper Dive into JavaScript's Oddities

An in-depth look at swapping variables using the bitwise XOR trick in JavaScript: how it works, why it sometimes bends expectations, practical use-cases, and the pitfalls you must know (ToInt32 conversion, aliasing, typed arrays, BigInt).