You are on page 1of 15

Open in app Get started

Published in Level Up Coding

You have 2 free member-only stories left this month. Sign up for Medium and get an extra one

Henrik Larsen Toft Follow

Jun 5 · 3 min read · Listen

Save

20 JavaScript snippets that will make you a


better developer
Almost all problems we developers face every day can be solved by solving a set of lesser
problems — Small solutions to single well-defined problems. These solutions can best be
described as «pure functions».
Open in app Get started

Photo by Blake Connally on Unsplash

Although most of these functions are implemented in different libraries — it’s important
to understand how and when to break difficult problems into smaller ones. This way of
thinking about problem solving will increase your productivity and make you a better
developer.

Below is a unordered collection of 20 useful «pure functions» I use on a regular basis to


solve all kinds of problems.

Get value
Given an object or array — the function will return the value at specified path,
otherwise null.

1 const getValue = (obj, path) => path


2 .replace(/\[([^[\]]*)]/g, '.$1.')
3 .split('.')
4 .filter(prop => prop !== '')
5 .reduce((prev, next) => (
6 prev instanceof Object ? prev[next] : undefined
7 ), obj);
8
9 getValue({ a: { b: { c: 'd' } } }, 'a.b.c'); // = d
10 getValue({ a: { b: { c: [1, 2] } } }, 'a.b.c[1]'); // = 2

getValue.js
hosted with ❤ by GitHub view raw
Clamp Open in app Get started

Ensure a value is within a specified range, otherwise “clamp” to the closest of the minimum

and maximum value.

1 const clamp = (min, max, value) => {


2 if (min > max) throw new Error('min cannot be greater than max');
3 return value < min
4 ? min
5 : value > max
6 ? max
7 : value;
8 }
9
10 clamp(0, 10, -5); // = 0
11 clamp(0, 10, 20); // = 10

clamp.js
hosted with ❤ by GitHub view raw

Sleep
Wait the specified duration in milliseconds before performing the next operation.

1 const sleep = async (duration) => (


2 new Promise(resolve =>
3 setTimeout(resolve, duration)
4 )
5 );
6
7 await sleep(1000); // waits 1 sec
7 await sleep(1000); // waits 1 sec

sleep.js
hosted with ❤ by GitHub Open in app Get started
view raw

Group by
Group and index related items in an object according to the keying-function.

1 const groupBy = (fn, list) => (


2 list.reduce((prev, next) => ({
3 ...prev,
4 [fn(next)]: [...(prev[fn(next)] || []), next]
5 }), {})
6 );
7
8 groupBy(vehicle => vehicle.make, [
9 { make: 'tesla', model: '3' },
10 { make: 'tesla', model: 'y' },
11 { make: 'ford', model: 'mach-e' },
12 ]);
13
14 // {
15 // tesla: [ { make: 'tesla', ... }, { make: 'tesla', ... } ],
16 // ford: [ { make: 'ford', ... } ],
17 // }

groupBy.js
hosted with ❤ by GitHub view raw
Open in app Get started

Collect By
Create sub-lists containing related items according to the keying-function.

1 import groupBy from './groupBy';


2
3 const collectBy = (fn, list) =>
4 Object.values(groupBy(fn, list));
5
6 collectBy(vehicle => vehicle.make, [
7 { make: 'tesla', model: '3' },
8 { make: 'tesla', model: 'y' },
9 { make: 'ford', model: 'mach-e' },
10 ]);
11
12 // [
13 // [ { make: 'tesla', ... }, { make: 'tesla', ... } ],
14 // [ { make: 'ford', ... } ],
15 // ]

collectBy.js
hosted with ❤ by GitHub view raw
Open in app Get started

Head
Get the first element of a list. This function is useful for writing clean and readable code.

1 const head = list => list[0];


2
3 head([1, 2, 3]); // = 1
4 head([]); // = undefined

head.js
hosted with ❤ by GitHub view raw

Tail
Get all but the first element of a list. This function is useful for writing clean and readable
code.

1 const tail = list => list.slice(1);


2
3 tail([1, 2, 3]); // = [2, 3]
4 tail([]); // = []

tail.js
hosted with ❤ by GitHub view raw

288 3

Flatten
Create a flat list by pulling all items from nested sub-lists recursively.
1 const flatten = list => list.reduce((prev, next) => ([ Open in app Get started
2 ...prev,
3 ...(Array.isArray(next) ? flatten(next) : [next])
4 ]), []);
5
6 flatten([[1, 2, [3, 4], 5, [6, [7, 8]]]]); // = [1, 2, 3, 4, 5, 6, 7, 8]

flatten.js
hosted with ❤ by GitHub view raw

Intersection By
Find all values that are present in both lists as defined by a keying-function.

1 const intersectionBy = (fn, listA, listB) => {


2 const b = new Set(listB.map(fn));
3 return listA.filter(val => b.has(fn(val)));
4 };
5
6 intersectionBy(v => v, [1, 2, 3], [2, 3, 4]); // = [2, 3]
7 intersectionBy(v => v.a, [{ a: 1 }, { a: 2 }], [{ a: 2}, { a: 3 }, { a: 4 }]); // = [{ a: 2

intersectionBy.js
hosted with ❤ by GitHub view raw

Index By
Index each element in a list by a value determined by the keying-function.
1 const indexBy = (fn, list) => Open in app Get started
2 list.reduce((prev, next) => ({
3 ...prev,
4 [fn(next)]: next
5 }), {});
6
7 indexBy(val => val.a, [{ a: 1 }, { a: 2 }, { a: 3 }]);
8 // = { 1: { a: 1 }, 2: { a:2 }, 3: { a: 3 } }
9

indexBy.js
hosted with ❤ by GitHub view raw

Difference By
Find all items in the first list that are not present in the second list — determined by the
keying-function.

1 import indexBy from './indexBy';


2
3 const differenceBy = (fn, listA, listB) => {
4 const bIndex = indexBy(fn, listb);
5 return listA.filter(val => !bIndex[fn(val)]);
6 });
7
8 differenceBy(val => val, [1,2,3], [3,4,5]); // = [1,2]
9 differenceBy(
10 vehicle => vehicle.make,
11 [{ make: 'tesla' }, { make: 'ford' }, { make: 'gm' }],
12 [{ make: 'tesla' }, { make: 'bmw' }, { make: 'audi' }],
13 ); // = [{ make: 'ford' }, { make: 'gm' }]

differenceBy.js
hosted with ❤ by GitHub view raw
Open in app Get started

Recover With
Return the default value if the given function throws an Error .

1 const recoverWith = async (defaultValue, fn, ...args) => {


2 try {
3 const result = await fn(...args);
4 return result;
5 } catch (_e) {
6 return defaultValue;
7 }
8 }
9
10 recoverWith('A', val => val, 'B'); // = B
11 recoverWith('A', () => { throw new Error() }); // = 'A'

recoverWith.js
hosted with ❤ by GitHub view raw
Open in app Get started

Distance
Calculate the Euclidean distance between two points p1 & p2 .

1 const distance = ([x0, y0], [x1, y1]) => (


2 Math.hypot(x1 - x0, y1 - y0)
3 );
4
5 distance([0, 1], [5, 4]); // = 5.8309518948453

distance.js
hosted with ❤ by GitHub view raw

Drop While
Drops elements from the list, beginning at the first element, until som predicate is met.

1 const dropWhile = (pred, list) => {


2 let index = 0;
3 list.every(elem => {
4 index++;
5 return pred(elem);
6 });
7 return list.slice(index-1);
8 }
9
10 dropWhile(val => (val < 5), [1,2,3,4,5,6,7]); // = [5,6,7]

dropWhile.js
hosted with ❤ by GitHub view raw
Open in app Get started

Sum By
Calculate the sum of all elements in a list given some function that produce the individual
value of each element.

1 const sumBy = (fn, list) =>


2 list.reduce((prev, next) => prev + fn(next), 0);
3
4 sumBy(product => product.price, [
5 { name: 'pizza', price: 10 },
6 { name: 'pepsi', price: 5 },
7 { name: 'salad', price: 5 },
8 ]); // = 20

sumBy.js
hosted with ❤ by GitHub view raw

Ascending
Creates a ascending comparator-function given a valuating function.

1 const ascending = (fn) => (a, b) => {


2 const valA = fn(a);
3 const valB = fn(b);
4 return valA < valB ? -1 : valA > valB ? 1 : 0;
5 }
6
7 const byPrice = ascending(val => val.price);
8 [{ price: 300 }, { price: 100 }, { price: 200 }].sort(byPrice);
8 [{ price: 300 }, { price: 100 }, { price: 200 }].sort(byPrice);
9 // = [{ price: 100 }, { price: 200 }, { price: 300 }]
Open in app Get started
ascending.js
hosted with ❤ by GitHub view raw

Descending
Creates a descending comparator-function given a valuating function.

1 const descending = (fn) => (a, b) => {


2 const valA = fn(b);
3 const valB = fn(a);
4 return valA < valB ? -1 : valA > valB ? 1 : 0;
5 }
6
7 const byPrice = descending(val => val.price);
8 [{ price: 300 }, { price: 100 }, { price: 200 }].sort(byPrice);
9 // = [{ price: 300 }, { price: 200 }, { price: 100 }]

descending.js
hosted with ❤ by GitHub view raw

Find Key
Find the first key within an index that satisfies the given predicate
Find the first key within an index that satisfies the given predicate.
Open in app Get started

1 const findKey = (predicate, index) => Object


2 .keys(index)
3 .find(key => predicate(index[key], key, index));
4
5 findKey(
6 car => !car.available,
7 {
8 tesla: { available: true },
9 ford: { available: false },
10 gm: { available: true }
11 },
12 ); // = "ford"

findKey.js
hosted with ❤ by GitHub view raw

Bifurcate By
Split the values of a given list into two lists, one containing values the predicate function
evaluates to truthy, the other list containing the falsy.

1 const bifurcateBy = (predicate, list) =>


2 list.reduce((acc, val, i) => (
3 acc[predicate(val, i) ? 0 : 1].push(val), acc),
4 [[], []]
5 );
6
7 bifurcateBy(val => val > 0, [-1, 2, -3, 4]);
8 // = [[2, 4], [-1, -3]]
bifurcateBy.js
hosted with ❤ by GitHub Open in app
view raw
Get started

Pipe
Perform left-to-right function composition. All extra arguments will be passed to the first
function in the list, thus can have any arity. The result will be passed on the second, and
the result of the second will be passed to third,… and so on until all functions have been
processed.

1 const pipe = (functions, ...args) => (


2 functions.reduce(
3 (prev, next) => Array.isArray(prev) ? next(...prev) : next(prev),
4 args
5 )
6 );
7 pipe([Math.abs, Math.floor, val => -val], 4.20); // = -4
8 pipe([(a, b) => a - b, Math.abs], 5, 10); // = 5

pipe.js
hosted with ❤ by GitHub view raw
Final Thoughts Open in app Get started

Though all these functions can be really useful to help you solve the problems you are
working on — the most important lesson is knowing how to break complex and difficult
problems into small well defined problems that can be solved independently. Once you
master this — then you are already on your way of becoming an excellent developer!

Thanks for reading and hope you enjoyed!

Sign up for Top Stories


By Level Up Coding

A monthly summary of the best stories shared in Level Up Coding Take a look.

Get this newsletter

About Help Terms Privacy

Get the Medium app

You might also like