286 Favorite JavaScript Utilities

in single line of code! No more!

GitHub ★ 4378
Array

Cast a value as an array
#

const castArray = value => Array.isArray(value) ? value : [value];

// Examples
castArray(1); // [1]
castArray([1, 2, 3]); // [1, 2, 3]

Check if an array is empty
#

// `arr` is an array
const isEmpty = arr => !Array.isArray(arr) || arr.length === 0;

// Examples
isEmpty([]); // true
isEmpty([1, 2, 3]); // false

Clone an array
#

// `arr` is an array
const clone = arr => arr.slice(0);

// Or
const clone = arr => [...arr];

// Or
const clone = arr => Array.from(arr);

// Or
const clone = arr => arr.map(x => x);

// Or
const clone = arr => JSON.parse(JSON.stringify(arr));

// Or
const clone = arr => arr.concat([]);

Compare two arrays
#

// `a` and `b` are arrays
const isEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);

// Or
const isEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);

// Examples
isEqual([1, 2, 3], [1, 2, 3]); // true
isEqual([1, 2, 3], [1, '2', 3]); // false

Compare two arrays regardless of order
#

// `a` and `b` are arrays
const isEqual = (a, b) => JSON.stringify(a.sort()) === JSON.stringify(b.sort());

// Examples
isEqual([1, 2, 3], [1, 2, 3]); // true
isEqual([1, 2, 3], [1, 3, 2]); // true
isEqual([1, 2, 3], [1, '2', 3]); // false

Convert an array of objects to a single object
#

const toObject = (arr, key) => arr.reduce((a, b) => ({ ...a, [b[key]]: b }), {});

// Example
toObject(
[
{ id: '1', name: 'Alpha', gender: 'Male' },
{ id: '2', name: 'Bravo', gender: 'Male' },
{ id: '3', name: 'Charlie', gender: 'Female' },
],
'id'
);
/*
{
'1': { id: '1', name: 'Alpha', gender: 'Male' },
'2': { id: '2', name: 'Bravo', gender: 'Male' },
'3': { id: '3', name: 'Charlie', gender: 'Female' },
}
*/

Convert an array of strings to numbers
#

const toNumbers = arr => arr.map(Number);

// Or
const toNumbers = arr => arr.map(x => +x);

// Example
toNumbers(['2', '3', '4']); // [2, 3, 4]

Count by the properties of an array of objects
#

const countBy = (arr, prop) => arr.reduce((prev, curr) => (prev[curr[prop]] = ++prev[curr[prop]] || 1, prev), {});

// Example
countBy([
{ branch: 'audi', model: 'q8', year: '2019' },
{ branch: 'audi', model: 'rs7', year: '2020' },
{ branch: 'ford', model: 'mustang', year: '2019' },
{ branch: 'ford', model: 'explorer', year: '2020' },
{ branch: 'bmw', model: 'x7', year: '2020' },
], 'branch');

// { 'audi': 2, 'ford': 2, 'bmw': 1 }

Count the occurrences of a value in an array
#

const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a), 0);

// Or
const countOccurrences = (arr, val) => arr.filter(item => item === val).length;

// Examples
countOccurrences([2, 1, 3, 3, 2, 3], 2); // 2
countOccurrences(['a', 'b', 'a', 'c', 'a', 'b'], 'a'); // 3

Count the occurrences of array elements
#

const countOccurrences = arr => arr.reduce((prev, curr) => (prev[curr] = ++prev[curr] || 1, prev), {});

// Examples
countOccurrences([2, 1, 3, 3, 2, 3]); // { '1': 1, '2': 2, '3': 3 }
countOccurrences(['a', 'b', 'a', 'c', 'a', 'b']); // { 'a': 3, 'b': 2, 'c': 1 }

Create an array of cumulative sum
#

const accumulate = arr => arr.map((sum => value => sum += value)(0));

// Or
const accumulate = arr => arr.reduce((a, b, i) => i === 0 ? [b] : [...a, b + a[i - 1]], []);

// Or
const accumulate = arr => arr.reduce((a, b, i) => i === 0 ? [b] : [...a, b + a[i - 1]], 0);

// Example
accumulate([1, 2, 3, 4]); // [1, 3, 6, 10]
// 1 = 1
// 1 + 2 = 3
// 1 + 2 + 3 = 6
// 1 + 2 + 3 + 4 = 10

Create an array of numbers in the given range
#

const range = (min, max) => [...Array(max - min + 1).keys()].map(i => i + min);

// Or
const range = (min, max) => Array(max - min + 1).fill(0).map((_, i) => min + i);

// Or
const range = (min, max) => Array.from({ length: max - min + 1 }, (_, i) => min + i);

// Example
range(5, 10); // [5, 6, 7, 8, 9, 10]

Create cartesian product
#

const cartesian = (...sets) => sets.reduce((acc, set) => acc.flatMap((x) => set.map((y) => [...x, y])), [[]]);

// Example
cartesian([1, 2], [3, 4]); // [ [1, 3], [1, 4], [2, 3], [2, 4] ]

/*
3 4
---------------
1 | [1, 3] [1, 4]
|
2 | [2, 3] [2, 4]

*/

Empty an array
#

const empty = arr => arr.length = 0;

// Or
arr = [];

Find the closest number from an array
#

// Find the number from `arr` which is closest to `n`
const closest = (arr, n) => arr.reduce((prev, curr) => Math.abs(curr - n) < Math.abs(prev - n) ? curr : prev);

// Or
const closest = (arr, n) => arr.sort((a, b) => Math.abs(a - n) - Math.abs(b - n))[0];

// Example
closest([29, 87, 8, 78, 97, 20, 75, 33, 24, 17], 50); // 33

Find the index of the last matching item of an array
#

const lastIndex = (arr, predicate) => arr.reduce((prev, curr, index) => predicate(curr) ? index : prev, -1);

// Or
const lastIndex = (arr, predicate) => arr.map(item => predicate(item)).lastIndexOf(true);

// Example
lastIndex([1, 3, 5, 7, 9, 2, 4, 6, 8], i => i % 2 === 1); // 4
lastIndex([1, 3, 5, 7, 9, 8, 6, 4, 2], i => i > 6); // 5

Find the index of the maximum item of an array
#

const indexOfMax = arr => arr.reduce((prev, curr, i, a) => curr > a[prev] ? i : prev, 0);

// Examples
indexOfMax([1, 3, 9, 7, 5]); // 2
indexOfMax([1, 3, 7, 7, 5]); // 2

Find the index of the minimum item of an array
#

const indexOfMin = arr => arr.reduce((prev, curr, i, a) => curr < a[prev] ? i : prev, 0);

// Examples
indexOfMin([6, 4, 8, 2, 10]); // 3
indexOfMin([6, 4, 2, 2, 10]); // 2

Find the length of the longest string in an array
#

const findLongest = words => Math.max(...(words.map(el => el.length)));

// Example
findLongest(['always','look','on','the','bright','side','of','life']); // 6

Find the maximum item of an array
#

const max = arr => Math.max(...arr);

Find the maximum item of an array by given key
#

const maxBy = (arr, key) => arr.reduce((a, b) => a[key] >= b[key] ? a : b, {});

// Example
const people = [
{ name: 'Bar', age: 24 },
{ name: 'Baz', age: 32 },
{ name: 'Foo', age: 42 },
{ name: 'Fuzz', age: 36 },
];
maxBy(people, 'age'); // { name: 'Foo', age: 42 }

Find the minimum item of an array
#

const min = arr => Math.min(...arr);

Find the minimum item of an array by given key
#

const minBy = (arr, key) => arr.reduce((a, b) => a[key] < b[key] ? a : b, {});

// Example
const people = [
{ name: 'Bar', age: 24 },
{ name: 'Baz', age: 32 },
{ name: 'Foo', age: 42 },
{ name: 'Fuzz', age: 36 },
];
minBy(people, 'age'); // { name: 'Bar', age: 24 }

Flatten an array
#

const flat = arr => [].concat.apply([], arr.map(a => Array.isArray(a) ? flat(a) : a));
// Or
const flat = arr => arr.reduce((a, b) => Array.isArray(b) ? [...a, ...flat(b)] : [...a, b], []);

// Or
// See the browser compatibility at https://caniuse.com/#feat=array-flat
const flat = arr => arr.flat();

// Example
flat(['cat', ['lion', 'tiger']]); // ['cat', 'lion', 'tiger']

Get all arrays of consecutive elements
#

const getConsecutiveArrays = (arr, size) => size > arr.length ? [] : arr.slice(size - 1).map((_, i) => arr.slice(i, size + i));

// Examples
getConsecutiveArrays([1, 2, 3, 4, 5], 2); // [[1, 2], [2, 3], [3, 4], [4, 5]]
getConsecutiveArrays([1, 2, 3, 4, 5], 3); // [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
getConsecutiveArrays([1, 2, 3, 4, 5], 6); // []

Get all n-th items of an array
#

const getNthItems = (arr, nth) => arr.filter((_, i) => i % nth === nth - 1);

// Examples
getNthItems([1, 2, 3, 4, 5, 6, 7, 8, 9], 2); // [2, 4, 6, 8]
getNthItems([1, 2, 3, 4, 5, 6, 7, 8, 9], 3); // [3, 6, 9]

Get all subsets of an array
#

const getSubsets = arr => arr.reduce((prev, curr) => prev.concat(prev.map(k => k.concat(curr))), [[]]);

// Examples
getSubsets([1, 2]); // [[], [1], [2], [1, 2]]
getSubsets([1, 2, 3]); // [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]

Get indices of a value in an array
#

const indices = (arr, value) => arr.reduce((acc, v, i) => (v === value ? [...acc, i] : acc), []);

// Or
const indices = (arr, value) => arr.map((v, i) => v === value ? i : false).filter(Boolean);

// Examples
indices(['h', 'e', 'l', 'l', 'o'], 'l'); // [2, 3]
indices(['h', 'e', 'l', 'l', 'o'], 'w'); // []

Get the average of an array
#

const average = arr => arr.reduce((a, b) => a + b, 0) / arr.length;

Get the intersection of arrays
#

const getIntersection = (a, ...arr) => [...new Set(a)].filter(v => arr.every(b => b.includes(v)));

// Examples
getIntersection([1, 2, 3], [2, 3, 4, 5]); // [2, 3]
getIntersection([1, 2, 3], [2, 3, 4, 5], [1, 3, 5]); // [3]

Get the rank of an array of numbers
#

const ranking = (arr) => arr.map((x, y, z) => z.filter(w => w > x).length + 1);

// Examples
ranking([80, 65, 90, 50]); // [2, 3, 1, 4]
ranking([80, 80, 70, 50]); // [1, 1, 3, 4]
ranking([80, 80, 80, 50]); // [1, 1, 1, 4]

Get the sum of an array of numbers
#

const sum = arr => arr.reduce((a, b) => a + b, 0);

Get the unique values of an array
#

const unique = arr => [...new Set(arr)];

// Or
const unique = arr => arr.filter((el, i, array) => array.indexOf(el) === i);

// Or
const unique = arr => arr.reduce((acc, el) => acc.includes(el) ? acc : [...acc, el], []);

Get union of arrays
#

const union = (...arr) => [...new Set(arr.flat())];

// Example
union([1, 2], [2, 3], [3]); // [1, 2, 3]

Group an array of objects by a key
#

const groupBy = (arr, key) => arr.reduce((acc, item) => ((acc[item[key]] = [...(acc[item[key]] || []), item]), acc), {});

// Example
groupBy([
{ branch: 'audi', model: 'q8', year: '2019' },
{ branch: 'audi', model: 'rs7', year: '2020' },
{ branch: 'ford', model: 'mustang', year: '2019' },
{ branch: 'ford', model: 'explorer', year: '2020' },
{ branch: 'bmw', model: 'x7', year: '2020' },
], 'branch');

/*
{
audi: [
{ branch: 'audi', model: 'q8', year: '2019' },
{ branch: 'audi', model: 'rs7', year: '2020' }
],
bmw: [
{ branch: 'bmw', model: 'x7', year: '2020' }
],
ford: [
{ branch: 'ford', model: 'mustang', year: '2019' },
{ branch: 'ford', model: 'explorer', year: '2020' }
],
}
*/

Merge two arrays
#

// Merge but don't remove the duplications
const merge = (a, b) => a.concat(b);
// Or
const merge = (a, b) => [...a, ...b];

// Merge and remove the duplications
const merge = [...new Set(a.concat(b))];
// Or
const merge = [...new Set([...a, ...b])];

Partition an array based on a condition
#

const partition = (arr, criteria) => arr.reduce((acc, i) => (acc[criteria(i) ? 0 : 1].push(i), acc), [[], []]);

// Example
partition([1, 2, 3, 4, 5], n => n % 2); // [[2, 4], [1, 3, 5]]

Remove duplicate values in an array
#

const removeDuplicate = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));

// Example
removeDuplicate(['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']); // ['h', 'e', 'w', 'r', 'd']

Remove falsy values from array
#

const removeFalsy = arr => arr.filter(Boolean);

// Example
removeFalsy([0, 'a string', '', NaN, true, 5, undefined, 'another string', false]); // ['a string', true, 5, 'another string']

Repeat an array
#

// `arr` is an array
const repeat = (arr, n) => [].concat(...Array(n).fill(arr));

// Or
const repeat = (arr, n) => Array(n).fill(arr).flat();

// Or
const repeat = (arr, n) => Array(arr.length * n).fill(0).map((_, i) => arr[i % arr.length]);

// Or
const repeat = (arr, n) => Array.from({ length: arr.length * n }, (_, i) => arr[i % arr.length]);

// Examples
repeat([1, 2, 3], 3); // [1, 2, 3, 1, 2, 3, 1, 2, 3]

Shuffle an array
#

const shuffle = arr => arr.map(a => ({ sort: Math.random(), value: a })).sort((a, b) => a.sort - b.sort).map(a => a.value);

// Or
const shuffle = arr => arr.sort(() => .5 - Math.random());

// Example
shuffle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); // [9, 1, 10, 6, 8, 5, 2, 3, 7, 4]

Sort an array of items by given key
#

const sortBy = (arr, k) => arr.concat().sort((a, b) => (a[k] > b[k]) ? 1 : ((a[k] < b[k]) ? -1 : 0));

// Example
const people = [
{ name: 'Foo', age: 42 },
{ name: 'Bar', age: 24 },
{ name: 'Fuzz', age: 36 },
{ name: 'Baz', age: 32 },
];
sortBy(people, 'age');

// returns
// [
// { name: 'Bar', age: 24 },
// { name: 'Baz', age: 32 },
// { name: 'Fuzz', age: 36 },
// { name: 'Foo', age: 42 },
// ]

Sort an array of numbers
#

const sort = arr => arr.sort((a, b) => a - b);

// Example
sort([1, 5, 2, 4, 3]); // [1, 2, 3, 4, 5]

Split an array into chunks
#

const chunk = (arr, size) => arr.reduce((acc, e, i) => (i % size ? acc[acc.length - 1].push(e) : acc.push([e]), acc), []);

// Examples
chunk([1, 2, 3, 4, 5, 6, 7, 8], 3); // [[1, 2, 3], [4, 5, 6], [7, 8]]
chunk([1, 2, 3, 4, 5, 6, 7, 8], 4); // [[1, 2, 3, 4], [5, 6, 7, 8]]

Swap the rows and columns of a matrix
#

const transpose = matrix => matrix[0].map((col, i) => matrix.map(row => row[i]));

// Or
const transpose = matrix => matrix[0].map((col, c) => matrix.map((row, r) => matrix[r][c]));

// Or
const transpose = matrix => matrix.reduce((prev, next) => next.map((item, i) => (prev[i] || []).concat(next[i])), []);

// Example
transpose([ // [
[1, 2, 3], // [1, 4, 7],
[4, 5, 6], // [2, 5, 8],
[7, 8, 9], // [3, 6, 9],
]); // ]

Swap two array items
#

// `i` must be less than `j`
const swapItems = (a, i, j) => a[i] && a[j] && [...a.slice(0, i), a[j], ...a.slice(i + 1, j), a[i], ...a.slice(j + 1)] || a;

// Example
swapItems([1, 2, 3, 4, 5], 1, 4); // [1, 5, 3, 4, 2]

Unzip an array of arrays
#

const unzip = arr => arr.reduce((acc, c) => (c.forEach((v, i) => acc[i].push(v)), acc), Array.from({ length: Math.max(...arr.map(a => a.length)) }, (_) => []));

// Example
unzip([['a', 1], ['b', 2], ['c', 3], ['d', 4], ['e', 5]]); // [['a', 'b', 'c', 'd', 'e'], [1, 2, 3, 4, 5]]

/*
a 1
b 2
c 3
d 4
e 5
*/

Zip multiple arrays
#

const zip = (...arr) => Array.from({ length: Math.max(...arr.map(a => a.length)) }, (_, i) => arr.map(a => a[i]));

// Example
zip(['a', 'b', 'c', 'd', 'e'], [1, 2, 3, 4, 5]); // [['a', 1], ['b', 2], ['c', 3], ['d', 4], ['e', 5]]

/*
Does it look like a zipper?
a 1
b 2
c 3
d 4
e 5
*/
DOM

Check if an element is a descendant of another
#

const isDescendant = (child, parent) => parent.contains(child);

Check if an element is focused
#

const hasFocus = ele => (ele === document.activeElement);

Check if the touch events are supported
#

const touchSupported = () => ('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch);

Check if user scrolls to the bottom of the page
#

const isAtBottom = () => document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight;

Detect Internet Explorer browser
#

const isIE = !!document.documentMode;

Detect macOS browser
#

const isMacBrowser = /Mac|iPod|iPhone|iPad/.test(navigator.platform);

Get all siblings of an element
#

const siblings = ele => [].slice.call(ele.parentNode.children).filter((child) => (child !== ele));

Get the position of an element relative to the document
#

const getPosition = ele => (r = ele.getBoundingClientRect(), { left: r.left + window.scrollX, top: r.top + window.scrollY });

// Example
getPosition(document.body); // { left: 0, top: 0 }

Get the selected text
#

const getSelectedText = () => window.getSelection().toString();

Go back to the previous page
#

history.back();

// Or
history.go(-1);

Hide an element
#

// Pick the method that is suitable for your use case
const hide = ele => ele.style.display = 'none';

// Or
const hide = ele => ele.style.visibility = 'hidden';

// Or
const hide = ele => ele.hidden = true;

Insert an element after other one
#

const insertAfter = (ele, anotherEle) => anotherEle.parentNode.insertBefore(ele, anotherEle.nextSibling);

// Or
const insertAfter = (ele, anotherEle) => anotherEle.insertAdjacentElement('afterend', ele);

Insert an element before other one
#

const insertBefore = (ele, anotherEle) => anotherEle.parentNode.insertBefore(ele, anotherEle);

// Or
const insertBefore = (ele, anotherEle) => anotherEle.insertAdjacentElement('beforebegin', ele);

Insert given HTML after an element
#

const insertHtmlAfter = (html, ele) => ele.insertAdjacentHTML('afterend', html);

Insert given HTML before an element
#

const insertHtmlBefore = (html, ele) => ele.insertAdjacentHTML('beforebegin', html);

Redirect to another page
#

const goTo = url => location.href = url;

Reload the current page
#

const reload = () => location.reload();

// Or
const reload = () => (location.href = location.href);

Replace an element
#

const replace = (ele, newEle) => ele.parentNode.replaceChild(newEle, ele);

Scroll to top of the page
#

const goToTop = () => window.scrollTo(0, 0);

Serialize form data
#

const serialize = formEle => Array.from(new FormData(formEle)).reduce((p, [k, v]) => Object.assign({}, p, { [k]: p[k] ? (Array.isArray(p[k]) ? p[k] : [p[k]]).concat(v) : v}), {});

Show an element
#

const show = ele => ele.style.display = '';

Strip HTML from a given text
#

const stripHtml = html => (new DOMParser().parseFromString(html, 'text/html')).body.textContent || '';

Toggle an element
#

const toggle = ele => (ele.style.display = (ele.style.display === 'none') ? 'block' : 'none');

// Or
const toggle = ele => ele.hidden = !ele.hidden;
Date Time

Add AM PM suffix to an hour
#

// `h` is an hour number between 0 and 23
const suffixAmPm = h => `${h % 12 === 0 ? 12 : h % 12}${h < 12 ? 'am' : 'pm'}`;

// Examples
suffixAmPm(0); // '12am'
suffixAmPm(5); // '5am'
suffixAmPm(12); // '12pm'
suffixAmPm(15); // '3pm'
suffixAmPm(23); // '11pm'

Calculate the number of difference days between two dates
#

const diffDays = (date, otherDate) => Math.ceil(Math.abs(date - otherDate) / (1000 * 60 * 60 * 24));

// Example
diffDays(new Date('2014-12-19'), new Date('2020-01-01')); // 1839

Calculate the number of months between two dates
#

const monthDiff = (startDate, endDate) => Math.max(0, (endDate.getFullYear() - startDate.getFullYear()) * 12 - startDate.getMonth() + endDate.getMonth());

// Example
monthDiff(new Date('2020-01-01'), new Date('2021-01-01')); // 12

Compare two dates
#

// `a` and `b` are `Date` instances
const compare = (a, b) => a.getTime() > b.getTime();

// Example
compare(new Date('2020-03-30'), new Date('2020-01-01')); // true

Convert a date to YYYY-MM-DD format
#

// `date` is a `Date` object
const formatYmd = date => date.toISOString().slice(0, 10);

// Example
formatYmd(new Date()); // 2020-05-06

Convert seconds to hh:mm:ss format
#

// `s` is number of seconds
const formatSeconds = s => new Date(s * 1000).toISOString().substr(11, 8);

// Or
const formatSeconds = s => (new Date(s * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];

// Or
const formatSeconds = s => [parseInt(s / 60 / 60), parseInt(s / 60 % 60), parseInt(s % 60)].join(':').replace(/\b(\d)\b/g, '0$1');

// Examples
formatSeconds(200); // 00:03:20
formatSeconds(500); // 00:08:20

Extract year, month, day, hour, minute, second and millisecond from a date
#

// `date` is a `Date` object
const extract = date => date.toISOString().split(/[^0-9]/).slice(0, -1);

// `extract` is an array of [year, month, day, hour, minute, second, millisecond]

Format a date for the given locale
#

// `date` is a `Date` object
// `locale` is a locale (en-US, pt-BR, for example)
const format = (date, locale) => new Intl.DateTimeFormat(locale).format(date);

// Example
format(new Date(), 'pt-BR'); // 06/05/2020

Get the current quarter of a date
#

const getQuarter = (d = new Date()) => Math.ceil((d.getMonth() + 1) / 3);

Get the current timestamp in seconds
#

const ts = () => Math.floor(new Date().getTime() / 1000);

Get the day of the year from a date
#

// `date` is a Date object
const dayOfYear = date => Math.floor((date - new Date(date.getFullYear(), 0, 0)) / (1000 * 60 * 60 * 24));

// Example
dayOfYear(new Date(2020, 04, 16)); // 137

Get the first date in the month of a date
#

const getFirstDate = (d = new Date()) => new Date(d.getFullYear(), d.getMonth(), 1);

Get the last date in the month of a date
#

const getLastDate = (d = new Date()) => new Date(d.getFullYear(), d.getMonth() + 1, 0);

Get the month name of a date
#

// `date` is a Date object
const getMonthName = date => ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October',' November', 'December'][date.getMonth()];

Get the number of days in given month
#

// `month` is zero-based index
const daysInMonth = (month, year) => new Date(year, month, 0).getDate();

Get the timezone string
#

const getTimezone = () => Intl.DateTimeFormat().resolvedOptions().timeZone;

// Example
getTimezone(); // 'Asia/Saigon'

Get the tomorrow date
#

const tomorrow = (d => new Date(d.setDate(d.getDate() + 1)))(new Date);

// Or
const tomorrow = new Date((new Date()).valueOf() + 1000 * 60 * 60 * 24);

Get the total number of days in a year
#

const numberOfDays = year => (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)) ? 366 : 365;

// Or
const numberOfDays = year => new Date(year, 1, 29).getDate() === 29 ? 366 : 365;

Get the weekday of a date
#

// `date` is a Date object
const getWeekday = date => ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][date.getDay()];

Get the yesterday date
#

const yesterday = (d => new Date(d.setDate(d.getDate() - 1)))(new Date);

// Or
const yesterday = new Date((new Date()).valueOf() - 1000 * 60 * 60 * 24);

Initialize the current date but set time to midnight
#

const midnightOfToday = () => new Date(new Date().setHours(0, 0, 0, 0));

Sort an array of dates
#

// `arr` is an array of `Date` items
const sortDescending = arr => arr.sort((a, b) => a.getTime() > b.getTime());
const sortAscending = arr => arr.sort((a, b) => a.getTime() < b.getTime());
Function

Box handler
#

const boxHandler = x => ({ next: f => boxHandler(f(x)), done: f => f(x) });

// Example 1
const getPercentNumber = str => boxHandler(str).next(str => str.replace(/\%/, '')).next(str => parseFloat(str)).done(res => res * 0.01);

getPercentNumber('50%'); // 0.5

// Example 2
const getMoney = (price) => Number.parseFloat(price.replace(/\$/, ''));
const getPercent = (percent) => Number.parseFloat(percent.replace(/\%/)) * 0.01;

const getDiscountPrice = (price, discount) => boxHandler(getMoney(price)).done(cents => boxHandler(getPercent(discount)).next(save => cents - (cents * save))).done(res => res);

getDiscountPrice('$6.00', '20%'); // 4.8

Check if a value is a function
#

const isFunction = v => ['[object Function]', '[object GeneratorFunction]', '[object AsyncFunction]', '[object Promise]'].includes(Object.prototype.toString.call(v));

// Examples
isFunction(function() {}); // true
isFunction(function*() {}); // true
isFunction(async function() {}); // true

Check if a value is a generator function
#

const isGeneratorFunction = v => Object.prototype.toString.call(v) === '[object GeneratorFunction]';

// Examples
isGeneratorFunction(function() {}); // false
isGeneratorFunction(function*() {}); // true

Check if a value is an async function
#

const isAsyncFunction = v => Object.prototype.toString.call(v) === '[object AsyncFunction]';

// Examples
isAsyncFunction(function() {}); // false
isAsyncFunction(function*() {}); // false
isAsyncFunction(async function() {}); // true

Compose functions
#

// Compose functions from right to left
const compose = (...fns) => x => fns.reduceRight((y, f) => f(y), x);

// Example
const lowercase = str => str.toLowerCase();
const capitalize = str => `${str.charAt(0).toUpperCase()}${str.slice(1)}`;
const reverse = str => str.split('').reverse().join('');

const fn = compose(reverse, capitalize, lowercase);

// We will execute `lowercase`, `capitalize` and `reverse` in order
fn('Hello World') === 'dlrow olleH';

Compose functions from left to right
#

// Compose functions from left to right
const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);

// Example
const lowercase = str => str.toLowerCase();
const capitalize = str => `${str.charAt(0).toUpperCase()}${str.slice(1)}`;
const reverse = str => str.split('').reverse().join('');

const fn = pipe(lowercase, capitalize, reverse);

// We will execute `lowercase`, `capitalize` and `reverse` in order
fn('Hello World') === 'dlrow olleH';

Create a function that accepts a single argument
#

const unary = fn => arg => fn(arg);

// Example
['1', '2', '3', '4', '5'].map(unary(parseInt)); // [1, 2, 3, 4, 5]

Create an empty function
#

const noop = () => {};

// Or
const noop = Function();
// calling Function() might be detected as using eval by some security tools

Curry a function
#

const curry = (fn, ...args) => fn.length <= args.length ? fn(...args) : curry.bind(null, fn, ...args);

// Example
const sum = (a, b, c) => a + b + c;
curry(sum)(1)(2)(3); // 6
curry(sum)(1, 2, 3); // 6
curry(sum, 1)(2, 3); // 6
curry(sum, 1)(2)(3); // 6
curry(sum, 1, 2)(3); // 6
curry(sum, 1, 2, 3); // 6

Delay the evaluation of a function
#

// returns a new version of `fn` that returns values as lazy evaluable
const thunkfy = fn => (...args) => () => fn(...args);

// Example
const heavyComputation = x => doStuff(x);
const unnecessarySlow = manyThings.map(heavyComputation)
.find(result => result.criteria);
const probablyFaster = manyThings.map(thunkfy(heavyComputation))
.find(thunk => thunk().criteria);

Execute a function once
#

const once = fn => ((ran = false) => () => ran ? fn : (ran = !ran, fn = fn()))();

// Example
let n = 0;
const incOnce = once(() => ++n);
incOnce(); // n = 1
incOnce(); // n = 1
incOnce(); // n = 1

Flip the arguments of a function
#

// Reverse the order of arguments
const flip = fn => (...args) => fn(...args.reverse());

// For binary functions
const flip = fn => (b, a) => fn(a, b);

// Or for curried functions
const flip = fn => b => a => fn(a)(b);

// Example
const isParent = (parent, child) => parent.children.includes(child);
const isChild = flip(isParent);

Identity function
#

const identity = x => x;

Logical xor operator
#

// returns `true` if one of the arguments is truthy and the other is falsy

const xor = (a, b) => (a && !b) || (!a && b);

// Or
const xor = (a, b) => !(!a && !b) && !(a && b);

// Or
const xor = (a, b) => Boolean(!a ^ !b);

// Examples
xor(true, true); // false
xor(false, false); // false
xor(true, false); // true
xor(false, true); // true

Memoize a function
#

const memoize = fn => ((cache = {}) => arg => cache[arg] || (cache[arg] = fn(arg)))();

// Example
// Calculate Fibonacci numbers
const fibo = memoize(n => n <= 2 ? 1 : fibo(n - 1) + fibo(n - 2));

fibo(1); // 1
fibo(2); // 1
fibo(3); // 2
fibo(4); // 3
fibo(5); // 5
fibo(6); // 8

Partially apply a function
#

const partial = (fn, ...a) => (...b) => fn(...a, ...b);

// Example
const sum = (x, y) => x + y;
const inc = partial(sum, 1);
inc(9); // 10

Uncurry a function
#

// `fn` is a curried function
// `n` is the depth of parameters
const uncurry = (fn, n = 1) => (...args) => (acc => args => args.reduce((x, y) => x(y), acc))(fn)(args.slice(0, n));

// Example
const sum = a => b => c => a + b + c;
uncurry(sum, 1)(1)(2)(3); // 6
uncurry(sum, 2)(1, 2)(3); // 6
uncurry(sum, 3)(1, 2, 3); // 6
Math

Calculate the angle of a line defined by two points
#

// In radians
const radiansAngle = (p1, p2) => Math.atan2(p2.y - p1.y, p2.x - p1.x);

// In degrees
const degreesAngle = (p1, p2) => Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;

Calculate the distance between two points
#

const distance = (p1, p2) => Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));

Calculate the linear interpolation between two numbers
#

const lerp = (a, b, amount) => (1 - amount) * a + amount * b;

Calculate the midpoint between two points
#

const midpoint = (p1, p2) => [(p1.x + p2.x) / 2, (p1.y + p2.y) / 2];

Check if a point is inside a rectangle
#

const isInside = (point, rect) => point.x > rect.left && point.x < rect.right && point.y > rect.top && point.y < rect.bottom;

Check if a rectangle contains other one
#

// Returns true if `a` contains `b`
// (x1, y1) and (x2, y2) are top-left and bottom-right corners
const contains = (a, b) => (a.x1 <= b.x1 && a.y1 <= b.y1 && a.x2 >= b.x2 && a.y2 >= b.y2);

Check if a rectangle overlaps other one
#

// Returns true if `a` overlaps `b`
// (x1, y1) and (x2, y2) are top-left and bottom-right corners
const overlaps = (a, b) => (a.x1 < b.x2 && b.x1 < a.x2) || (a.y1 < b.y2 && b.y1 < a.y2);

Convert degrees to radians
#

const degsToRads = deg => deg * Math.PI / 180.0;

Convert radians to degrees
#

const radsToDegs = rad => rad * 180 / Math.PI;

Normalize the ratio of a number in a range
#

const normalizeRatio = (value, min, max) => (value - min) / (max - min);

Round a number to the nearest multiple of a given value
#

const roundNearest = (value, nearest) => Math.round(value / nearest) * nearest;

// Examples
roundNearest(100, 30); // 90
roundNearest(200, 30); // 210
roundNearest(200, 40); // 200
Misc

Check if the code is running in NodeJS
#

const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;

Check if the code is running in the browser
#

const isBrowser = typeof window === 'object' && typeof document === 'object';

Clear all cookies
#

const clearCookies = document.cookie.split(';').forEach(c => document.cookie = c.replace(/^ +/, '').replace(/=.*/, `=;expires=${new Date().toUTCString()};path=/`));

Convert 3 digits color to 6 digits color
#

const toFullHexColor = color => `#${(color.startsWith('#') ? color.slice(1) : color).split('').map(c => `${c}${c}`).join('')}`;

// Example
toFullHexColor('123'); // '#112233'
toFullHexColor('#123'); // '#112233'
toFullHexColor('#abc'); // '#aabbcc'

Convert Celsius to Fahrenheit
#

const celsiusToFahrenheit = celsius => celsius * 9/5 + 32;

// Examples
celsiusToFahrenheit(15); // 59
celsiusToFahrenheit(0); // 32
celsiusToFahrenheit(-20); // -4

Convert Fahrenheit to Celsius
#

const fahrenheitToCelsius = fahrenheit => (fahrenheit - 32) * 5/9;

// Examples
fahrenheitToCelsius(59); // 15
fahrenheitToCelsius(32); // 0

Convert hex to rgb
#

const hexToRgb = hex => hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (_, r, g, b) => `#${r}${r}${g}${g}${b}${b}`).substring(1).match(/.{2}/g).map(x => parseInt(x, 16));

// Examples
hexToRgb('#00ffff'); // [0, 255, 255]
hexToRgb('#0ff'); // [0, 255, 255]

Convert rgb color to hex
#

const rgbToHex = (red, green, blue) => `#${((1 << 24) + (red << 16) + (green << 8) + blue).toString(16).slice(1)}`;

// Or
const rgbToHex = (red, green, blue) => `#${[red, green, blue].map(v => v.toString(16).padStart(2, '0')).join('')}`;

// Example
rgbToHex(0, 255, 255); // '#00ffff'

Convert URL parameters to object
#

const getUrlParams = query => Array.from(new URLSearchParams(query)).reduce((p, [k, v]) => Object.assign({}, p, { [k]: p[k] ? (Array.isArray(p[k]) ? p[k] : [p[k]]).concat(v) : v}), {});

// Examples
getUrlParams(location.search); // Get the parameters of the current URL

getUrlParams('foo=Foo&bar=Bar'); // { foo: "Foo", bar: "Bar" }

// Duplicate key
getUrlParams('foo=Foo&foo=Fuzz&bar=Bar'); // { foo: ["Foo", "Fuzz"], bar: "Bar" }

Decode a JWT token
#

const decode = token => decodeURIComponent(atob(token.split('.')[1].replace('-', '+').replace('_', '/')).split('').map(c => `%${('00' + c.charCodeAt(0).toString(16)).slice(-2)}`).join(''));

// Example
decode(`
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0I
joxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
`
);

// { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }

Detect dark mode
#

const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;

Easing functions
#

// Some easing functions
// See https://gist.github.com/gre/1650294 and https://easings.net

const linear = t => t;

const easeInQuad = t => t * t;
const easeOutQuad = t => t * (2-t);
const easeInOutQuad = t => t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;

const easeInCubic = t => t * t * t;
const easeOutCubic = t => (--t) * t * t + 1;
const easeInOutCubic = t => t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;

const easeInQuart = t => t * t * t * t;
const easeOutQuart = t => 1 - (--t) * t * t * t;
const easeInOutQuart = t => t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t;

const easeInQuint = t => t * t * t * t * t;
const easeOutQuint = t => 1 + (--t) * t * t * t * t;
const easeInOutQuint = t => t < .5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t;

const easeInSine = t => 1 + Math.sin(Math.PI / 2 * t - Math.PI / 2);
const easeOutSine = t => Math.sin(Math.PI / 2 * t);
const easeInOutSine = t => (1 + Math.sin(Math.PI * t - Math.PI / 2)) / 2;

const easeInElastic = t => (.04 - .04 / t) * Math.sin(25 * t) + 1;
const easeOutElastic = t => .04 * t / (--t) * Math.sin(25 * t);
const easeInOutElastic = t => (t -= .5) < 0 ? (.02 + .01 / t) * Math.sin(50 * t) : (.02 - .01 / t) * Math.sin(50 * t) + 1;

Emulate a dice throw
#

const throwdice = () => ~~(Math.random() * 6) + 1;

// Examples
throwdice(); // 4
throwdice(); // 1
throwdice(); // 6

Encode a URL
#

// `encodeURIComponent` doesn't encode -_.!~*'()
const encode = url => encodeURIComponent(url).replace(/!/g, '%21').replace(/~/g, '%7E').replace(/\*/g, '%2A').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/%20/g, '+');

Generate an unique and increment id
#

const uid = (() => (id = 0, () => id++))();

// Examples
uid(); // 0
uid(); // 1
uid(); // 2
uid(); // 3

Get the first defined and non null argument
#

const coalesce = (...args) => args.find(item => item !== undefined && item !== null);

// Or
const coalesce = (...args) => args.find(item => ![undefined, null].includes(item));

// Examples
coalesce(undefined, null, 'helloworld', NaN); // 'helloworld'

Get the value of a param from a URL
#

const getParam = (url, param) => new URLSearchParams(new URL(url).search).get(param);

// Example
getParam('http://domain.com?message=hello', 'message'); // 'hello'

Get type of a variable in string
#

const getTypeOf = obj => Object.prototype.toString.call(obj).match(/\[object (.*)\]/)[1];

// Examples
getTypeOf('hello world'); // String
getTypeOf(1000); // Number
getTypeOf(Infinity); // Number
getTypeOf(true); // Boolean
getTypeOf(Symbol()); // Symbol
getTypeOf(null); // Null
getTypeOf(undefined); // Undefined
getTypeOf({}); // Object
getTypeOf([]); // Array
getTypeOf(/[a-z]/g); // RegExp
getTypeOf(new Date(2021)); // Date
getTypeOf(new Error()); // Error
getTypeOf(function() {}); // Function
getTypeOf((a, b) => a + b); // Function
getTypeOf(async () => {}); // AsyncFunction
getTypeOf(document); // HTMLDocument

Redirect the page to HTTPS if it is in HTTP
#

const redirectHttps = () => (location.protocol === 'https:') ? {} : location.replace(`https://${location.href.split('//')[1]}`);

// Or
const redirectHttps = () => (location.protocol === 'https:') ? {} : (location.protocol = 'https:');

Run Promises in sequence
#

// `promises` is an array of `Promise`
const run = promises => promises.reduce((p, c) => p.then(rp => c.then(rc => [...rp, rc])), Promise.resolve([]));

// Example
run(promises).then((results) => {
// `results` is an array of promise results in the same order
});

Swap two variables
#

[a, b] = [b, a];

// Or
a = [b, b = a][0];

// Or
a = (x => x)(b, b = a);

// Or
// (only works with numbers)
a = b + (b = a, 0);

a = b * (b = a, 1);

Wait for an amount of time
#

const wait = async (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
Number

Add an ordinal suffix to a number
#

// `n` is a position number
const addOrdinal = n => `${n}${['st', 'nd', 'rd'][((n + 90) % 100 - 10) % 10 - 1] || 'th'}`;

// Or
const addOrdinal = n => `${n}${[, 'st', 'nd', 'rd'][/1?.$/.exec(n)] || 'th'}`;

// Or
const addOrdinal = n => `${n}${[, 'st', 'nd', 'rd'][n % 100 >> 3^1 && n % 10] || 'th'}`;

// Or
const addOrdinal = n => `${n}${{one: 'st', two: 'nd', few: 'rd', other: 'th'}[new Intl.PluralRules('en', { type: 'ordinal' }).select(n)]}`;

// Examples
addOrdinal(1); // '1st'
addOrdinal(2); // '2nd'
addOrdinal(3); // '3rd'
addOrdinal(11); // '11th'
addOrdinal(12); // '13th'
addOrdinal(13); // '13th'

Calculate Fibonacci numbers
#

const fibo = (n, memo = {}) => memo[n] || (n <= 2 ? 1 : (memo[n] = fibo(n - 1, memo) + fibo(n - 2, memo)));

// Examples
fibo(1); // 1
fibo(2); // 1
fibo(3); // 2
fibo(4); // 3
fibo(5); // 5
fibo(6); // 8

Calculate the average of arguments
#

const average = (...args) => args.reduce((a, b) => a + b) / args.length;

// Example
average(1, 2, 3, 4); // 2.5

Calculate the division of arguments
#

const division = (...args) => args.reduce((a, b) => a / b);

// Example
division(1, 2, 3, 4); // 0.04166666666666666

Calculate the factorial of a number
#

const factorial = n => n <= 1 ? 1 : n * factorial(n - 1);

// Examples
factorial(2); // 2
factorial(3); // 6
factorial(4); // 24
factorial(5); // 120
factorial(6); // 720

Calculate the mod of collection index
#

const mod = (a, b) => ((a % b) + b) % b;

// Examples
mod(-1, 5); // 4
mod(3, 5); // 3
mod(6, 5); // 1

Calculate the remainder of division of arguments
#

const remainder = (...args) => args.reduce((a, b) => a % b);

// Example
remainder(1, 2, 3, 4); // 1

Calculate the sum of arguments
#

const sum = (...args) => args.reduce((a, b) => a + b);

// Example
sum(1, 2, 3, 4); // 10

Clamp a number between two values
#

const clamp = (val, min = 0, max = 1) => Math.max(min, Math.min(max, val));

// Example
clamp(199, 10, 25); // 25

Compute the greatest common divisor between two numbers
#

const gcd = (a, b) => b === 0 ? a : gcd(b, a % b);

// Example
gcd(10, 15); // 5

Convert a number to equivalent characters
#

const toChars = n => `${n >= 26 ? toChars(Math.floor(n / 26) - 1) : ''}${'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[n % 26]}`;

// Examples
toChars(0); // A
toChars(1); // B
toChars(25); // Z

toChars(26); // AA
toChars(27); // AB
toChars(51); // AZ

toChars(701); // ZZ
toChars(702); // AAA
toChars(703); // AAB

Convert a string to number
#

const toNumber = str => +str;

// Example
toNumber('42'); // 42

Convert decimal to binary recursively
#

const decToBi = num => num === 0 ? 0 : num % 2 + 10 * decToBi(~~(num / 2));


// Example
decToBi(10); //1010

Get the arrays of digits from a number
#

const digitize = n => `${n}`.split('').map(v => parseInt(v, 10));

// Or
const digitize = n => [...`${n}`].map(v => parseInt(v, 10));

// Example
digitize(123); // [1, 2, 3]

Multiply arguments
#

const mul = (...args) => args.reduce((a, b) => a * b);

// Example
mul(1, 2, 3, 4); // 24

Prefix an integer with zeros
#

const prefixWithZeros = (number, length) => (number / Math.pow(10, length)).toFixed(length).substr(2);

// Or
const prefixWithZeros = (number, length) => `${Array(length).join('0')}${number}`.slice(-length);

// Or
const prefixWithZeros = (number, length) => String(number).padStart(length, '0');

// Example
prefixWithZeros(42, 5); // '00042'

Round a number to a given number of digits
#

const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`);

// Examples
round(1.234567, 3); // 1.235
round(1.234567, 4); // 1.2346

Subtract arguments
#

const subtract = (...args) => args.reduce((a, b) => a - b);

// Example
subtract(1, 2, 3, 4); // -8

Truncate a number at decimal
#

const truncate = n => ~~n;

// Examples
truncate(25.198726354); // 25
truncate(-25.198726354); // -25

Truncate a number to a given number of decimal places without rounding
#

const toFixed = (n, fixed) => `${n}`.match(new RegExp(`^-?\\d+(?:\.\\d{0,${fixed}})?`))[0];

// Or
const toFixed = (n, fixed) => ~~(Math.pow(10, fixed) * n) / Math.pow(10, fixed);

// Examples
toFixed(25.198726354, 1); // 25.1
toFixed(25.198726354, 2); // 25.19
toFixed(25.198726354, 3); // 25.198
toFixed(25.198726354, 4); // 25.1987
toFixed(25.198726354, 5); // 25.19872
toFixed(25.198726354, 6); // 25.198726
Object

Check if multiple objects are equal
#

const isEqual = (...objects) => objects.every(obj => JSON.stringify(obj) === JSON.stringify(objects[0]));

// Examples
isEqual({ foo: 'bar' }, { foo: 'bar' }); // true
isEqual({ foo: 'bar' }, { bar: 'foo' }); // false

Create an empty map that does not have properties
#

// `map` doesn't have any properties
const map = Object.create(null);

// The following `map` has `__proto__` property
// const map = {};

Create an object from the pairs of key and value
#

const toObj = arr => Object.fromEntries(arr)

// Or
const toObj = arr => arr.reduce((a, c) => ((a[c[0]] = c[1]), a), {});

// Example
toObj([['a', 1], ['b', 2], ['c', 3]]); // { a: 1, b: 2, c: 3 }

Extract values of a property from an array of objects
#

const pluck = (objs, property) => objs.map(obj => obj[property]);

// Example
pluck([
{ name: 'John', age: 20 },
{ name: 'Smith', age: 25 },
{ name: 'Peter', age: 30 },
], 'name'); // ['John', 'Smith', 'Peter']

Get the value at given path of an object
#

const getValue = (path, obj) => path.split('.').reduce((acc, c) => acc && acc[c], obj);

// Example
getValue('a.b', { a: { b: 'Hello World' } }); // 'Hello World';

Immutably rename object keys
#

const renameKeys = (keysMap, obj) => Object.keys(obj).reduce((acc, key) => ({ ...acc, ...{ [keysMap[key] || key]: obj[key] }}), {});

// Examples
const obj = { a: 1, b: 2, c: 3 };
const keysMap = { a: 'd', b: 'e', c: 'f' };
renameKeys(keysMap, obj); // { d: 1, e: 2, f: 3 }

Invert keys and values of an object
#

const invert = obj => Object.keys(obj).reduce((res, k) => Object.assign(res, {[obj[k]]: k}), {});

// Or
const invert = obj => Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]));

// Example
invert({ a: '1', b: '2', c: '3' }); // { 1: 'a', 2: 'b', 3: 'c' }

Omit a subset of properties from an object
#

const omit = (obj, keys) => Object.keys(obj).filter(k => !keys.includes(k)).reduce((res, k) => Object.assign(res, {[k]: obj[k]}), {});

// Example
omit({a: '1', b: '2', c: '3'}, ['a', 'b']); // { c: '3' }

Pick a subset of properties of an object
#

const pick = (obj, keys) => Object.keys(obj).filter(k => keys.includes(k)).reduce((res, k) => Object.assign(res, {[k]: obj[k]}), {});

// Example
pick({ a: '1', b: '2', c: '3' }, ['a', 'b']); // { a: '1', b: '2' }

Remove all null and undefined properties from an object
#

const removeNullUndefined = obj => Object.entries(obj).reduce((a, [k, v]) => (v == null ? a : (a[k] = v, a)), {});

// Or
const removeNullUndefined = obj => Object.entries(obj).filter(([_, v]) => v != null).reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});

// Or
const removeNullUndefined = obj => Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null));

// Example
removeNullUndefined({
foo: null,
bar: undefined,
fuzz: 42,
}); // { fuzz: 42 }

Shallow copy an object
#

const shallowCopy = obj => Object.assign({}, obj);

// or
const shallowCopy = obj => {...obj};

Sort an object by its properties
#

const sort = obj => Object.keys(obj).sort().reduce((p, c) => (p[c] = obj[c], p), {});

// Example
const colors = {
white: '#ffffff',
black: '#000000',
red: '#ff0000',
green: '#008000',
blue: '#0000ff',
};
sort(colors);
/*
{
black: '#000000',
blue: '#0000ff',
green: '#008000',
red: '#ff0000',
white: '#ffffff',
}
*/
Random

Generate a random boolean
#

const randomBoolean = () => Math.random() >= 0.5;

Generate a random floating point number in given range
#

const randomFloat = (min, max) => Math.random() * (max - min) + min;

Generate a random hex color
#

const randomColor = () => `#${Math.random().toString(16).slice(2, 8).padEnd(6, '0')}`;

// Or
const randomColor = () => `#${(~~(Math.random()*(1<<24))).toString(16)}`;

Generate a random integer in given range
#

const randomInteger = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;

Generate a random IP address
#

const randomIp = () => Array(4).fill(0).map((_, i) => Math.floor(Math.random() * 255) + (i === 0 ? 1 : 0)).join('.');

// Example
randomIp(); // 175.89.174.131

Generate a random sign
#

const randomSign = () => Math.random() >= 0.5 ? 1 : -1;

Generate a random string from given characters
#

const generateString = (length, chars) => Array(length).fill('').map((v) => chars[Math.floor(Math.random() * chars.length)]).join('');

// Example
generateString(10, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');

Generate a random string using Node crypto module
#

const randomStr = () => require('crypto').randomBytes(32).toString('hex');

Generate a random string with given length
#

const generateString = length => Array(length).fill('').map((v) => Math.random().toString(36).charAt(2)).join('');

Generate a random UUID
#

const uuid = (a) => a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid);

Generate an array of random integers in a given range
#

const randomArrayInRange = (min, max, n) => Array.from({ length: n }, () => Math.floor(Math.random() * (max - min + 1)) + min);

// Example
randomArrayInRange(1, 100, 10); // [11, 82, 41, 35, 76, 83, 43, 15, 60, 54]

Get a random item and remove it from an array
#

const randomItem = arr => arr.splice((Math.random() * arr.length) | 0, 1);

// Example
const arr = [1, 3, 5, 7, 9];
randomItem(arr); // 7
// arr = [1, 3, 5, 9]

Get a random item from an array
#

const randomItem = arr => arr[(Math.random() * arr.length) | 0];

Get random items of an array
#

const randomItems = (arr, count) => arr.concat().reduce((p, _, __, arr) => (p[0] < count) ? [p[0] + 1, p[1].concat(arr.splice(Math.random() * arr.length | 0, 1))] : p, [0, []])[1];

// Examples
randomItems([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3); // [4, 8, 5]
randomItems(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], 4); // ['e', 'c', 'h', 'j']

Pick a random property of an object
#

const randomProp = obj => Object.keys(obj)[(Math.random() * Object.keys(obj).length) | 0];

// Example
const colors = {
aqua: '#00ffff',
azure: '#f0ffff',
beige: '#f5f5dc',
black: '#000000',
blue: '#0000ff',
brown: '#a52a2a',
cyan: '#00ffff',
darkblue: '#00008b',
darkcyan: '#008b8b',
darkgrey: '#a9a9a9',
darkgreen: '#006400',
darkkhaki: '#bdb76b',
darkmagenta: '#8b008b',
darkolivegreen: '#556b2f',
darkorange: '#ff8c00',
darkorchid: '#9932cc',
darkred: '#8b0000',
darksalmon: '#e9967a',
darkviolet: '#9400d3',
fuchsia: '#ff00ff',
gold: '#ffd700',
green: '#008000',
indigo: '#4b0082',
khaki: '#f0e68c',
lightblue: '#add8e6',
lightcyan: '#e0ffff',
lightgreen: '#90ee90',
lightgrey: '#d3d3d3',
lightpink: '#ffb6c1',
lightyellow: '#ffffe0',
lime: '#00ff00',
magenta: '#ff00ff',
maroon: '#800000',
navy: '#000080',
olive: '#808000',
orange: '#ffa500',
pink: '#ffc0cb',
purple: '#800080',
violet: '#800080',
red: '#ff0000',
silver: '#c0c0c0',
white: '#ffffff',
yellow: '#ffff00',
};
randomProp(colors); // 'red'

Pick random lines from a text document
#

const randomLines = (str, count) => str.split(/\r?\n/).reduce((p, _, __, arr) => (p[0] < count) ? [p[0] + 1, p[1].concat(arr.splice(Math.random() * arr.length | 0, 1))] : p, [0, []])[1];

// Example
randomLines(`one
two
three
four
five
`
, 2);

// ['one', 'four']
String

Capitalize a string
#

const capitalize = str => `${str.charAt(0).toUpperCase()}${str.slice(1)}`;

// Or
const capitalize = ([first, ...rest]) => `${first.toUpperCase()}${rest.join('')}`;

// Example
capitalize('hello world'); // 'Hello world'

Check if a path is relative
#

const isRelative = path => !/^([a-z]+:)?[\\/]/i.test(path);

// Examples
isRelative('/foo/bar/baz'); // false
isRelative('C:\\foo\\bar\\baz'); // false
isRelative('foo/bar/baz.txt'); // true
isRelative('foo.md'); // true

Check if a string consists of a repeated character sequence
#

const consistsRepeatedSubstring = str => `${str}${str}`.indexOf(str, 1) !== str.length;

// Example
consistsRepeatedSubstring('aa'); // true
consistsRepeatedSubstring('aaa'); // true
consistsRepeatedSubstring('ababab'); // true
consistsRepeatedSubstring('abc'); // false

Check if a string is a palindrome
#

const isPalindrome = str => str === str.split('').reverse().join('');

// Examples
isPalindrome('abc'); // false
isPalindrom('abcba'); // true

Check if a URL is absolute
#

const isAbsoluteUrl = url => /^[a-z][a-z0-9+.-]*:/.test(url);

// Example
isAbsoluteUrl('https://1loc.dev'); // true
isAbsoluteUrl('https://1loc.dev/foo/bar'); // true
isAbsoluteUrl('1loc.dev'); // false
isAbsoluteUrl('//1loc.dev'); // false

Check if two strings are anagram
#

const areAnagram = (str1, str2) => str1.toLowerCase().split('').sort().join('') === str2.toLowerCase().split('').sort().join('');

// Examples
areAnagram('listen', 'silent'); // true
areAnagram('they see', 'the eyes'); // true
areAnagram('node', 'deno'); // true

Convert a letter to associate emoji
#

const letterToEmoji = c => String.fromCodePoint(c.toLowerCase().charCodeAt() + 127365);

// Examples
letterToEmoji('a'); // 🇦
letterToEmoji('b'); // 🇧

Convert a string to camelCase
#

const toCamelCase = str => str.trim().replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');

// Examples
toCamelCase('background-color'); // backgroundColor
toCamelCase('-webkit-scrollbar-thumb'); // WebkitScrollbarThumb
toCamelCase('_hello_world'); // HelloWorld
toCamelCase('hello_world'); // helloWorld

Convert a string to PascalCase
#

const toPascalCase = str => (str.match(/[a-zA-Z0-9]+/g) || []).map(w => `${w.charAt(0).toUpperCase()}${w.slice(1)}`).join('');

// Examples
toPascalCase('hello world'); // 'HelloWorld'
toPascalCase('hello.world'); // 'HelloWorld'
toPascalCase('foo_bar-baz'); // FooBarBaz

Convert a string to URL slug
#

const slugify = string => string.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]+/g, '');

// Example
slugify('Chapter One: Once upon a time...'); // 'chapter-one-once-upon-a-time'

Convert a Windows file path to Unix path
#

const toUnixPath = path => path.replace(/[\\/]+/g, '/').replace(/^([a-zA-Z]+:|\.\/)/, '');

// Examples
toUnixPath('./foo/bar/baz'); // foo/bar/baz
toUnixPath('C:\\foo\\bar\\baz'); // /foo/bar/baz

Convert camelCase to kebab-case and vice versa
#

const kebabToCamel = str => str.replace(/-./g, m => m.toUpperCase()[1]);

const camelToKebab = str => str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();

// Examples
kebabToCamel('background-color'); // 'backgroundColor'
camelToKebab('backgroundColor'); // 'background-color'

Convert snake_case to camelCase
#

const snakeToCamel = str => str.toLowerCase().replace(/(_\w)/g, m => m.toUpperCase().substr(1));

// Example
snakeToCamel('HELLO_world'); // 'helloWorld'

Convert the name of an Excel column to number
#

const getIndex = col => col.split('').reduce((prev, next) => prev * 26 + parseInt(next, 36) - 9, 0);

// Examples
getIndex('A'); // 1
getIndex('B'); // 2
getIndex('C'); // 3
getIndex('Z'); // 26

getIndex('AA'); // 27
getIndex('AB'); // 28
getIndex('AC'); // 29
getIndex('AZ'); // 52

getIndex('AAA'); // 703
getIndex('AAB'); // 704

Count the number of words in a string
#

const countWords = str => str.trim().split(/\s+/).length;

// Example
countWords('Hello World'); // 2
countWords('Hello World'); // 2
countWords(' Hello World '); // 2

Count the occurrences of a character in a string
#

const countOccurrences = (str, char) => [...str].reduce((a, v) => (v === char ? a + 1 : a), 0);

// Or
const countOccurrences = (str, char) => str.split('').reduce((a, v) => (v === char ? a + 1 : a), 0);

// Or
const countOccurrences = (str, char) => [...str].filter(item => item === char).length;

// Or
const countOccurrences = (str, char) => str.split('').filter(item => item === char).length;

// Examples
countOccurrences('a.b.c.d.e', '.'); // 4

Decapitalize a string
#

const decapitalize = str => `${str.charAt(0).toLowerCase()}${str.slice(1)}`;

// Or
const decapitalize = ([first, ...rest]) => `${first.toLowerCase()}${rest.join('')}`;

// Example
decapitalize('Hello world'); // 'hello world'

Escape HTML special characters
#

const escape = str => str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&#39;').replace(/"/g, '&quot;');

// Or
const escape = str => str.replace(/[&<>"']/g, m => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[m]);

Generate a hash of a string
#

const hash = str => str.split('').reduce((prev, curr) => Math.imul(31, prev) + curr.charCodeAt(0) | 0, 0);

// Or
const hash = str => str.split('').reduce((prev, curr) => (((prev << 5) - prev) + curr.charCodeAt(0)) | 0, 0);

// Example
hash('hello'); // 99162322

Get the base URL without any parameters
#

const baseUrl = url => url.indexOf('?') === -1 ? url : url.slice(0, url.indexOf('?'));

// Or
// Note that `includes` isn't supported in IE 11
const baseUrl = url => url.includes('?') ? url.slice(0, url.indexOf('?')) : url;

// Example
baseUrl('https://domain.com/path/sub/path?foo=bar&hello=world'); // 'https://domain.com/path/sub/path'

Get the file extension from a file name
#

const ext = fileName => fileName.split('.').pop();

Get the file name from a URL
#

const fileName = url => url.substring(url.lastIndexOf('/') + 1);

// Example
fileName('http://domain.com/path/to/document.pdf'); // 'document.pdf'

Get the length of a string in bytes
#

const bytes = str => new Blob([str]).size;

// Examples
bytes('hello world'); // 11
bytes('🎉'); // 4

Get the number of a character in a string
#

const characterCount = (str, char) => str.split(char).length - 1;

// Or
const characterCount = (str, char) => str.replace((new RegExp(String.raw`[^${char}]`, 'g')), '').length;

// Examples
characterCount('192.168.1.1', '.'); // 3
characterCount('star wars', 's'); // 2

Make the first character of a string lowercase
#

const lowercaseFirst = str => `${str.charAt(0).toLowerCase()}${str.slice(1)}`;

// Example
lowercaseFirst('Hello World'); // 'hello World'

Normalize file path slashes
#

const normalizePath = path => path.replace(/[\\/]+/g, '/');

// Example
normalizePath('\\foo\\bar\\baz\\'); // /foo/bar/baz/
normalizePath('.//foo//bar///////baz/'); // ./foo/bar/baz/

Prepend a line number to each line of a text document
#

const prependNumbers = str => str.split(/\r?\n/).map((line, i) => `${(i + 1).toString().padStart(2, ' ')} ${line}`).join('\n');

// Example
prependNumbers(`one
two
three
four
`
);

/* Output */
/*
1 one
2 two
3 three
4 four
*/

Remove duplicate lines of a text document
#

const removeDuplicateLines = str => Array.from(new Set(str.split(/\r?\n/))).join('\n');

// Example
removeDuplicateLines(`one
three
two
three
one
four
`
);

/* Output */
/*
one
three
two
four
*/

Remove empty lines of a text document
#

const removeEmptyLines = str => str.split(/\r?\n/).filter(line => line.trim() !== '').join('\n');

// Example
removeEmptyLines(`red

green
blue

yellow
`
);

/* Output */
/*
red
green
blue
yellow
*/

Remove spaces from a string
#

const removeSpaces = str => str.replace(/\s/g, '');

// Example
removeSpaces('hel lo wor ld'); // 'helloworld'

Repeat a string
#

const repeat = (str, numberOfTimes) => str.repeat(numberOfTimes);

// Or
const repeat = (str, numberOfTimes) => Array(numberOfTimes + 1).join(str);

Replace all line breaks with br elements
#

const nl2br = str => str.replace(new RegExp('\r?\n', 'g'), '<br>');

// In React
str.split('\n').map((item, index) => <React.Fragment key={index}>{item}<br /></React.Fragment>)

Replace all tab characters with spaces
#

const replace = (str, numSpaces = 4) => str.replaceAll('\t', ' '.repeat(numSpaces));

Replace multiple spaces with a single space
#

// Replace spaces, tabs and new line characters
const replaceSpaces = str => str.replace(/\s\s+/g, ' ');

// Only replace spaces
const replaceOnlySpaces = str => str.replace(/ +/g, ' ');

// Example
replaceSpaces('this\n is \ta \rmessage'); // 'this is a message'

Replace the first given number of characters of a string with another character
#

const mask = (str, num, mask) => `${str}`.slice(num).padStart(`${str}`.length, mask);

// Example
mask(1234567890, 3, '*'); // ***4567890

Reverse a string
#

const reverse = str => str.split('').reverse().join('');

// Or
const reverse = str => [...str].reverse().join('');

// Or
const reverse = str => str.split('').reduce((rev, char)=> `${char}${rev}`, '');

// Or
const reverse = str => (str === '') ? '' : `${reverse(str.substr(1))}${str.charAt(0)}`;

// Example
reverse('hello world'); // 'dlrow olleh'

Reverse the order of lines of a text
#

const reverseLines = str => str.split(/\r?\n/).reverse().join('\n');

// Example
reverseLines(`one
two
three
`
);

/* Output */
/*
three
two
one
*/

Sort lines of a text document in the alphabetical order
#

const sortLines = str => str.split(/\r?\n/).sort().join('\n');

// Reverse the order
const reverseSortedLines = str => str.split(/\r?\n/).sort().reverse().join('\n');

// Example
sortLines(`Thaddeus Mullen
Kareem Marshall
Ferdinand Valentine
Hasad Lindsay
Mufutau Berg
Knox Tyson
Kasimir Fletcher
Colton Sharp
Adrian Rosales
Theodore Rogers
`
);

/* Output */
/*
Adrian Rosales
Colton Sharp
Ferdinand Valentine
Hasad Lindsay
Kareem Marshall
Kasimir Fletcher
Knox Tyson
Mufutau Berg
Thaddeus Mullen
Theodore Rogers
*/

Sort the characters of a string in the alphabetical order
#

const sort = str => str.split('').sort((a, b) => a.localeCompare(b)).join('');

// Example
sort('hello world'); // dehllloorw

Strip ANSI codes from a string
#

const stripAnsiCodes = str => str.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '');

// Example
stripAnsiCodes('\u001B[4mcake\u001B[0m'); // 'cake'
stripAnsiCodes('\u001B[0m\u001B[4m\u001B[42m\u001B[31mfoo\u001B[39m\u001B[49m\u001B[24mfoo\u001B[0m'); // 'foofoo'

Swap case of characters in a string
#

const swapCase = str => str.split('').map(c => (c === c.toLowerCase() ? c.toUpperCase() : c.toLowerCase())).join('');

// Example
swapCase('Hello World'); // 'hELLO wORLD'

Trim slashes at the beginning and the end of a string
#

const trimSlashes = str => str.replace(/^\/+|\/+$/g, '');

// Or
const trimSlashes = str => str.split('/').filter(Boolean).join('/');

// Example
trimSlashes('//hello/world///'); // hello/world

Trim some character
#

const trim = (str, char) => str.split(char).filter(Boolean).join();

// Examples
trim('/hello world//', '/'); // hello world
trim('"hello world"', '"'); // hello world
trim(' hello world ', ' '); // hello world

Trim the file extension from a file name
#

const trimExt = fileName => fileName.indexOf('.') === -1 ? fileName : fileName.split('.').slice(0, -1).join('.');

// Examples
trimExt('document'); // document
trimExt('document.pdf'); // document
trimExt('document.2020.pdf'); // document.2020

Truncate a string at full words
#

const truncate = (str, max, suffix) => str.length < max ? str : `${str.substr(0, str.substr(0, max - suffix.length).lastIndexOf(' '))}${suffix}`;

// Example
truncate('This is a long message', 20, '...'); // 'This is a long...'

Unescape HTML special characters
#

const unescape = str => str.replace(/&amp;/g , '&').replace(/&lt;/g  , '<').replace(/&gt;/g  , '>').replace(/�*39;/g , "'").replace(/&quot;/g, '"');

Uppercase the first character of each word in a string
#

const uppercaseWords = str => str.split(' ').map(w => `${w.charAt(0).toUpperCase()}${w.slice(1)}`).join(' ');

// Or
const uppercaseWords = str => str.replace(/^(.)|\s+(.)/g, c => c.toUpperCase());

// Example
uppercaseWords('hello world'); // 'Hello World'
Validator

Check if a date is a weekday
#

// `date` is a Date object
const isWeekday = (date = new Date()) => date.getDay() % 6 !== 0;

Check if a date is a weekend
#

// `date` is a Date object
const isWeekend = (date = new Date()) => date.getDay() % 6 === 0;

Check if a date is between two dates
#

// `min`, `max` and `date` are `Date` instances
const isBetween = (date, min, max) => (date.getTime() >= min.getTime() && date.getTime() <= max.getTime());

Check if a date is today
#

// `date` is a Date object
const isToday = (date) => date.toISOString().slice(0, 10) === new Date().toISOString().slice(0, 10);

Check if a date occurs in the current year
#

// `date` is a Date object
const isCurrentYear = (date) => date.getUTCFullYear() === new Date().getUTCFullYear();

Check if a flat array has duplicate values
#

const hasDuplicateValues = arr => new Set(arr).size !== arr.length;

// Examples
hasDuplicateValues(['h', 'e', 'l', 'l', 'o']); // true
hasDuplicateValues(['w', 'o', 'r', 'd']); // false

Check if a given integer is a prime number
#

const isPrime = num => (num > 1) && Array(Math.floor(Math.sqrt(num)) - 1).fill(0).map((_, i) => i + 2).every(i => num % i !== 0);

Check if a number is a power of 2
#

const isPowerOfTwo = number => (number & (number - 1)) === 0;

// Examples
isPowerOfTwo(256); // true
isPowerOfTwo(129); // false

Check if a number is even
#

const isEven = number => number % 2 === 0;

// Or
const isEven = number => (number & 1) === 0;

// Or
const isEven = number => !(number & 1);

// Or
const isEven = number => Number.isInteger(number / 2);

// Examples
isEven(1); // false
isEven(2); // true

Check if a number is in a given range
#

const inRange = (num, a, b, threshold = 0) => (Math.min(a, b) - threshold <= num && num <= Math.max(a, b) + threshold);

// Example
inRange(10, 5, 15); // true
inRange(10, 5, 6); // false
inRange(10, 15, 5); // true
inRange(-10, -5, -15); // true

Check if a number is negative
#

const isNegative = number => Math.sign(number) === -1;

// Or
const isNegative = number => number < 0;

// Examples
isNegative(-3); // true
isNegative(8); // false

Check if a number is odd
#

const isOdd = number => number % 2 !== 0;

// Or
const isOdd = number => !!(number & 1);

// Or
const isOdd = number => !Number.isInteger(number / 2);

// Examples
isOdd(1); // true
isOdd(2); // false

Check if a number is positive
#

const isPositive = number => Math.sign(number) === 1;

// Examples
isPositive(3); // true
isPositive(-8); // false

Check if a string contains lower case characters
#

const containsLowerCase = str => str !== str.toUpperCase();

// Examples
containsLowerCase('Hello World'); // true
containsLowerCase('HELLO WORLD'); // false

Check if a string contains only ASCII characters
#

const isAscii = str => /^[\x00-\x7F]+$/.test(str);

Check if a string contains only digits
#

const isNumeric = str => !/[^0-9]/.test(str);

// Examples
isNumeric(2); // true
isNumeric('23'); // true
isNumeric('00123'); // true

isNumeric('1.23'); // false
isNumeric('-Infinity'); // false
isNumeric('Infinity'); // false
isNumeric('NaN'); // false

Check if a string contains only letters
#

const isAlpha = str => /^[A-Z]+$/i.test(str);

// Examples
isAlpha('helloworld'); // true
isAlpha('HelloWorld'); // true
isAlpha('hello world'); // false
isAlpha('0123456789'); // false

Check if a string contains only letters and numbers
#

const isAlphanumeric = str => /^[0-9A-Z]+$/i.test(str);

// Examples
isAlphanumeric('helloworld'); // true
isAlphanumeric('HelloWorld'); // true
isAlphanumeric('hello world'); // false
isAlphanumeric('hello123'); // true
isAlphanumeric('hello 123'); // false

Check if a string contains upper case characters
#

const containsUpperCase = str => str !== str.toLowerCase();

// Examples
containsUpperCase('Hello World'); // true
containsUpperCase('hello world'); // false

Check if a string contains whitespace
#

const containsWhitespace = str => str => /\s/.test(str);

// Example
containsWhitespace('hello world'); // true

Check if a string is a hexadecimal color
#

const isHexColor = color => /^#([0-9A-F]{3}|[0-9A-F]{4}|[0-9A-F]{6}|[0-9A-F]{8})$/i.test(color);

// Examples
isHexColor('#012'); // true
isHexColor('#A1B2C3'); // true
isHexColor('012'); // false
isHexColor('#GHIJKL'); // false

Check if a string is a hexadecimal number
#

const isHexadecimal = str => /^[A-F0-9]+$/i.test(str);

// Or
const isHexadecimal = str => str.split('').every(c => '0123456789ABCDEFabcdef'.indexOf(c) !== -1);

// Examples
isHexadecimal('123'); // true
isHexadecimal('A1B2C3'); // true
isHexadecimal('#123'); // false

Check if a string is a MongoDB ObjectId
#

const isMongoId = str => str.length === 24 && /^[A-F0-9]+$/i.test(str);

// Or
const isMongoId = str => str.length === 24 && str.split('').every(c => '0123456789ABCDEFabcdef'.indexOf(c) !== -1);

Check if a string is an octal number
#

const isOctal = str => /^(0o)?[0-7]+$/i.test(str);

Check if a string is lower case
#

const isLowerCase = str => str === str.toLowerCase();

Check if a string is upper case
#

const isUpperCase = str => str === str.toUpperCase();

Check if a value is a business identifier code
#

const isBIC = value => /^[a-zA-Z]{6}[a-zA-Z0-9]{2}([a-zA-Z0-9]{3})?$/.test(value);

Check if a value is a number
#

const isNumber = value => !isNaN(parseFloat(value)) && isFinite(value);

Check if a value is a plain object
#

const isPlainObject = v => (!!v && typeof v === 'object' && (v.__proto__ === null || v.__proto__ === Object.prototype));

// Examples
isPlainObject(null); // false
isPlainObject('hello world'); // false
isPlainObject([]); // false
isPlainObject(Object.create(null)); // false
isPlainObject(function() {}); // false

isPlainObject({}); // true
isPlainObject({ a: '1', b: '2' }); // true

Check if a value is a regular expression
#

const isRegExp = value => Object.prototype.toString.call(value) === '[object RegExp]';

Check if a value is a string
#

const isString = value => Object.prototype.toString.call(value) === '[object String]';

// Examples
isString('hello world'); // true
isString(new String('hello world')); // true
isString(10); // false

Check if a value is an object
#

const isObject = v => (v !== null && typeof v === 'object');

// Examples
isObject(null); // false
isObject('hello world'); // false

isObject({}); // true
isObject([]); // true

Check if a value is base32 encoded
#

const isBase32 = value => value.length % 8 === 0 && /^[A-Z2-7]+=*$/.test(value);

Check if a value is base58 encoded
#

// It doesn't accept the I, O, l characters 
const isBase58 = value => /^[A-HJ-NP-Za-km-z1-9]*$/.test(value);

Check if a value is base64 encoded
#

const isBase64 = value => /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$/.test(value);

Check if a value is nil
#

const isNil = (value) => value == null;

Check if a year is leap year
#

const isLeapYear = year => (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));

// Or
// Get the number of days in February
const isLeapYear = year => new Date(year, 1, 29).getDate() === 29;

Check if all array elements are equal to a given value
#

const isEqual = (arr, value) => arr.every(item => item === value);

// Or
// Ends earlier for false arrays
const isEqual = (arr, value) => !arr.some(item => item !== value);

// Examples
isEqual(['foo', 'foo'], 'foo'); // true
isEqual(['foo', 'bar'], 'foo'); // false
isEqual(['bar', 'bar'], 'foo'); // false

Check if all items in an array are equal
#

const areEqual = arr => arr.length > 0 && arr.every(item => item === arr[0]);

// Or
const areEqual = arr => new Set(arr).size === 1;

// Examples
areEqual([1, 2, 3, 4]); // false
areEqual(['hello', 'hello', 'hello']); // true

Check if an array contains a value matching some criterias
#

const contains = (arr, criteria) => arr.some(v => criteria(v));

// Or
const contains = (arr, criteria) => arr.some(criteria);

// Or
const contains = (arr,criteria) => arr.filter(criteria).length > 0;

// Examples
contains([10, 20, 30], v => v > 25 ); // true
contains([10, 20, 30], v => v > 100 || v < 15 ); // true
contains([10, 20, 30], v => v > 100 ); // false

Check if an array is not empty
#

const isNotEmpty = arr => Array.isArray(arr) && Object.keys(arr).length > 0;

// Examples
isNotEmpty([]); // false
isNotEmpty([1, 2, 3]); // true

Check if an array is subset of other array
#

// Check if `b` is subset of `a`
const isSubset = (a, b) => (new Set(b)).size === (new Set(b.concat(a))).size;

// Or
const isSubset = (a, b) => b.join("|").includes(a.join("|"));

// Examples
isSubset([1, 2], [1, 2, 3, 4]); // true
isSubset([1, 2, 5], [1, 2, 3, 4]); // false
isSubset([6], [1, 2, 3, 4]); // false

Check if an object is a Promise
#

const isPromise = obj => !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';

Check if an object is an array
#

const isArray = obj => Array.isArray(obj);

Check if an object is empty
#

const isEmpty = obj => Reflect.ownKeys(obj).length === 0 && obj.constructor === Object;

// Or for enumerable property names only
const isEmpty = obj => JSON.stringify(obj) === '{}';

Validate a Gregorian date
#

// `m`: the month (zero-based index)
// `d`: the day
// `y`: the year
const isValidDate = (m, d, y) => 0 <= m && m <= 11 && 0 < y && y < 32768 && 0 < d && d <= (new Date(y, m, 0)).getDate();