Skip to content

Instantly share code, notes, and snippets.

@mfrancois3k
Forked from bgoonz/code.js
Created March 4, 2022 08:07
Show Gist options
  • Save mfrancois3k/2fbd9cc02e51d81ba1b02162d30622df to your computer and use it in GitHub Desktop.
Save mfrancois3k/2fbd9cc02e51d81ba1b02162d30622df to your computer and use it in GitHub Desktop.
object-methods.js
function CSVToArray( data, delimiter = ',', omitFirstRow = false ) {
return data
.slice( omitFirstRow ? data.indexOf( '\n' ) + 1 : 0 )
.split( '\n' )
.map( v => v.split( delimiter ) );
}
CSVToArray( 'a,b\nc,d' ); // [['a', 'b'], ['c', 'd']];
CSVToArray( 'a;b\nc;d', ';' ); // [['a', 'b'], ['c', 'd']];
CSVToArray( 'col1,col2\na,b\nc,d', ',', true ); // [['a', 'b'], ['c', 'd']];
function CSVToJSON( data, delimiter = ',' ) {
const titles = data.slice( 0, data.indexOf( '\n' ) ).split( delimiter );
return data
.slice( data.indexOf( '\n' ) + 1 )
.split( '\n' )
.map( v => {
const values = v.split( delimiter );
return titles.reduce(
( obj, title, index ) => ( ( obj[ title ] = values[ index ] ), obj ),
{}
);
} );
}
CSVToJSON( 'col1,col2\na,b\nc,d' );
// [{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}];
CSVToJSON( 'col1;col2\na;b\nc;d', ';' );
// [{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}];
function CSVToArray( data, delimiter = ',', omitFirstRow = false ) {
return data
.slice( omitFirstRow ? data.indexOf( '\n' ) + 1 : 0 )
.split( '\n' )
.map( v => v.split( delimiter ) );
}
CSVToArray( 'a,b\nc,d' ); // [['a', 'b'], ['c', 'd']];
CSVToArray( 'a;b\nc;d', ';' ); // [['a', 'b'], ['c', 'd']];
CSVToArray( 'col1,col2\na,b\nc,d', ',', true ); // [['a', 'b'], ['c', 'd']];
function CSVToJSON( data, delimiter = ',' ) {
const titles = data.slice( 0, data.indexOf( '\n' ) ).split( delimiter );
return data
.slice( data.indexOf( '\n' ) + 1 )
.split( '\n' )
.map( v => {
const values = v.split( delimiter );
return titles.reduce(
( obj, title, index ) => ( ( obj[ title ] = values[ index ] ), obj ),
{}
);
} );
}
CSVToJSON( 'col1,col2\na,b\nc,d' );
// [{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}];
CSVToJSON( 'col1;col2\na;b\nc;d', ';' );
// [{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}];
const HSBToRGB = ( h, s, b ) => {
s /= 100;
b /= 100;
const k = ( n ) => ( n + h / 60 ) % 6;
const f = ( n ) => b * ( 1 - s * Math.max( 0, Math.min( k( n ), 4 - k( n ), 1 ) ) );
return [ 255 * f( 5 ), 255 * f( 3 ), 255 * f( 1 ) ];
};
HSBToRGB( 18, 81, 99 ); // [252.45, 109.31084999999996, 47.965499999999984]
function HSLToRGB( h, s, l ) {
s /= 100;
l /= 100;
const k = n => ( n + h / 30 ) % 12;
const a = s * Math.min( l, 1 - l );
const f = n => l - a * Math.max( -1, Math.min( k( n ) - 3, Math.min( 9 - k( n ), 1 ) ) );
return [ 255 * f( 0 ), 255 * f( 8 ), 255 * f( 4 ) ];
}
HSLToRGB( 13, 100, 11 ); // [56.1, 12.155, 0]
const fs = require( 'fs' );
const JSONToFile = ( obj, filename ) =>
fs.writeFileSync( `${ filename }.json`, JSON.stringify( obj, null, 2 ) );
JSONToFile( { test: 'is passed' }, 'testJsonFile' );
// writes the object to 'testJsonFile.json'
const JSONtoCSV = ( arr, columns, delimiter = ',' ) =>
[
columns.join( delimiter ),
...arr.map( obj =>
columns.reduce(
( acc, key ) =>
`${ acc }${ !acc.length ? '' : delimiter }"${ !obj[ key ] ? '' : obj[ key ] }"`,
''
)
),
].join( '\n' );
JSONtoCSV(
[ { a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 } ],
[ 'a', 'b' ]
); // 'a,b\n"1","2"\n"3","4"\n"6",""\n"","7"'
JSONtoCSV(
[ { a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 } ],
[ 'a', 'b' ],
';'
); // 'a;b\n"1";"2"\n"3";"4"\n"6";""\n"";"7"'
const RGBToHSB = ( r, g, b ) => {
r /= 255;
g /= 255;
b /= 255;
const v = Math.max( r, g, b ),
n = v - Math.min( r, g, b );
const h =
n === 0 ? 0 : n && v === r ? ( g - b ) / n : v === g ? 2 + ( b - r ) / n : 4 + ( r - g ) / n;
return [ 60 * ( h < 0 ? h + 6 : h ), v && ( n / v ) * 100, v * 100 ];
};
RGBToHSB( 252, 111, 48 );
// [18.529411764705856, 80.95238095238095, 98.82352941176471]
const RGBToHSL = ( r, g, b ) => {
r /= 255;
g /= 255;
b /= 255;
const l = Math.max( r, g, b );
const s = l - Math.min( r, g, b );
const h = s
? l === r
? ( g - b ) / s
: l === g
? 2 + ( b - r ) / s
: 4 + ( r - g ) / s
: 0;
return [
60 * h < 0 ? 60 * h + 360 : 60 * h,
100 * ( s ? ( l <= 0.5 ? s / ( 2 * l - s ) : s / ( 2 - ( 2 * l - s ) ) ) : 0 ),
( 100 * ( 2 * l - s ) ) / 2,
];
};
RGBToHSL( 45, 23, 11 ); // [21.17647, 60.71428, 10.98039]
const RGBToHex = ( r, g, b ) =>
( ( r << 16 ) + ( g << 8 ) + b ).toString( 16 ).padStart( 6, '0' );
RGBToHex( 255, 165, 1 ); // 'ffa501'
const URLJoin = ( ...args ) =>
args
.join( '/' )
.replace( /[\/]+/g, '/' )
.replace( /^(.+):\//, '$1://' )
.replace( /^file:/, 'file:/' )
.replace( /\/(\?|&|#[^!])/g, '$1' )
.replace( /\?/g, '&' )
.replace( '&', '?' );
URLJoin( 'http://www.google.com', 'a', '/b/cd', '?foo=123', '?bar=foo' );
// 'http://www.google.com/a/b/cd?foo=123&bar=foo'
const UUIDGeneratorBrowser = () =>
( [ 1e7 ] + -1e3 + -4e3 + -8e3 + -1e11 ).replace( /[018]/g, c =>
(
c ^
( crypto.getRandomValues( new Uint8Array( 1 ) )[ 0 ] & ( 15 >> ( c / 4 ) ) )
).toString( 16 )
);
UUIDGeneratorBrowser(); // '7982fcfe-5721-4632-bede-6000885be57d'
const crypto = require( 'crypto' );
const UUIDGeneratorNode = () =>
( [ 1e7 ] + -1e3 + -4e3 + -8e3 + -1e11 ).replace( /[018]/g, c =>
( c ^ ( crypto.randomBytes( 1 )[ 0 ] & ( 15 >> ( c / 4 ) ) ) ).toString( 16 )
);
UUIDGeneratorNode(); // '79c7c136-60ee-40a2-beb2-856f1feabefc'
const accumulate = ( ...nums ) =>
nums.reduce( ( acc, n ) => [ ...acc, n + +acc.slice( -1 ) ], [] );
accumulate( 1, 2, 3, 4 ); // [1, 3, 6, 10]
accumulate( ...[ 1, 2, 3, 4 ] ); // [1, 3, 6, 10]
const addClass = ( el, className ) => el.classList.add( className );
addClass( document.querySelector( 'p' ), 'special' );
// The paragraph will now have the 'special' class
const addDaysToDate = ( date, n ) => {
const d = new Date( date );
d.setDate( d.getDate() + n );
return d.toISOString().split( 'T' )[ 0 ];
};
addDaysToDate( '2020-10-15', 10 ); // '2020-10-25'
addDaysToDate( '2020-10-15', -10 ); // '2020-10-05'
const addEventListenerAll = ( targets, type, listener, options, useCapture ) => {
targets.forEach( target =>
target.addEventListener( type, listener, options, useCapture )
);
};
addEventListenerAll( document.querySelectorAll( 'a' ), 'click', () =>
console.log( 'Clicked a link' )
);
// Logs 'Clicked a link' whenever any anchor element is clicked
const addMinutesToDate = ( date, n ) => {
const d = new Date( date );
d.setTime( d.getTime() + n * 60000 );
return d.toISOString().split( '.' )[ 0 ].replace( 'T', ' ' );
};
addMinutesToDate( '2020-10-19 12:00:00', 10 ); // '2020-10-19 12:10:00'
addMinutesToDate( '2020-10-19', -10 ); // '2020-10-18 23:50:00'
const addMultipleListeners = ( el, types, listener, options, useCapture ) => {
types.forEach( type =>
el.addEventListener( type, listener, options, useCapture )
);
};
addMultipleListeners(
document.querySelector( '.my-element' ),
[ 'click', 'mousedown' ],
() => { console.log( 'hello!' ) }
);
const addStyles = ( el, styles ) => Object.assign( el.style, styles );
addStyles( document.getElementById( 'my-element' ), {
background: 'red',
color: '#ffff00',
fontSize: '3rem'
} );
const addWeekDays = ( startDate, count ) =>
Array.from( { length: count } ).reduce( date => {
date = new Date( date.setDate( date.getDate() + 1 ) );
if ( date.getDay() % 6 === 0 )
date = new Date( date.setDate( date.getDate() + ( date.getDay() / 6 + 1 ) ) );
return date;
}, startDate );
addWeekDays( new Date( 'Oct 09, 2020' ), 5 ); // 'Oct 16, 2020'
addWeekDays( new Date( 'Oct 12, 2020' ), 5 ); // 'Oct 19, 2020'
const all = ( arr, fn = Boolean ) => arr.every( fn );
all( [ 4, 2, 3 ], x => x > 1 ); // true
all( [ 1, 2, 3 ] ); // true
const allEqual = arr => arr.every( val => val === arr[ 0 ] );
allEqual( [ 1, 2, 3, 4, 5, 6 ] ); // false
allEqual( [ 1, 1, 1, 1 ] ); // true
const allEqualBy = ( arr, fn ) => {
const eql = fn( arr[ 0 ] );
return arr.every( val => fn( val ) === eql );
};
allEqualBy( [ 1.1, 1.2, 1.3 ], Math.round ); // true
allEqualBy( [ 1.1, 1.3, 1.6 ], Math.round ); // false
function allUnique( arr ) {
return arr.length === new Set( arr ).size;
}
allUnique( [ 1, 2, 3, 4 ] ); // true
allUnique( [ 1, 1, 2, 3 ] ); // false
function allUniqueBy( arr, fn ) {
return arr.length === new Set( arr.map( fn ) ).size;
}
allUniqueBy( [ 1.2, 2.4, 2.9 ], Math.round ); // true
allUniqueBy( [ 1.2, 2.3, 2.4 ], Math.round ); // false
const and = ( a, b ) => a && b;
and( true, true ); // true
and( true, false ); // false
and( false, false ); // false
const any = ( arr, fn = Boolean ) => arr.some( fn );
any( [ 0, 1, 2, 0 ], x => x >= 2 ); // true
any( [ 0, 0, 1, 0 ] ); // true
const aperture = ( n, arr ) =>
n > arr.length
? []
: arr.slice( n - 1 ).map( ( v, i ) => arr.slice( i, i + n ) );
aperture( 2, [ 1, 2, 3, 4 ] ); // [[1, 2], [2, 3], [3, 4]]
aperture( 3, [ 1, 2, 3, 4 ] ); // [[1, 2, 3], [2, 3, 4]]
aperture( 5, [ 1, 2, 3, 4 ] ); // []
const approximatelyEqual = ( v1, v2, epsilon = 0.001 ) =>
Math.abs( v1 - v2 ) < epsilon;
approximatelyEqual( Math.PI / 2.0, 1.5708 ); // true
const arithmeticProgression = ( n, lim ) =>
Array.from( { length: Math.ceil( lim / n ) }, ( _, i ) => ( i + 1 ) * n );
arithmeticProgression( 5, 25 ); // [5, 10, 15, 20, 25]
const arrayToCSV = ( arr, delimiter = ',' ) =>
arr
.map( v =>
v.map( x => ( isNaN( x ) ? `"${ x.replace( /"/g, '""' ) }"` : x ) ).join( delimiter )
)
.join( '\n' );
arrayToCSV( [ [ 'a', 'b' ], [ 'c', 'd' ] ] ); // '"a","b"\n"c","d"'
arrayToCSV( [ [ 'a', 'b' ], [ 'c', 'd' ] ], ';' ); // '"a";"b"\n"c";"d"'
arrayToCSV( [ [ 'a', '"b" great' ], [ 'c', 3.1415 ] ] );
// '"a","""b"" great"\n"c",3.1415'
function arrayToHTMLList( arr, listID ) {
return document.querySelector( `#${ listID }` ).innerHTML += arr
.map( item => `<li>${ item }</li>` )
.join( '' );
}
arrayToHTMLList( [ 'item 1', 'item 2' ], 'myListID' );
function ary( fn, n ) {
return ( ...args ) => fn( ...args.slice( 0, n ) );
}
const firstTwoMax = ary( Math.max, 2 );
[ [ 2, 6, 'a' ], [ 6, 4, 8 ], [ 10 ] ].map( x => firstTwoMax( ...x ) ); // [6, 6, 10]
function assertValidKeys( obj, keys ) {
return Object.keys( obj ).every( key => keys.includes( key ) );
}
assertValidKeys( { id: 10, name: 'apple' }, [ 'id', 'name' ] ); // true
assertValidKeys( { id: 10, name: 'apple' }, [ 'id', 'type' ] ); // false
const atob = str => Buffer.from( str, 'base64' ).toString( 'binary' );
atob( 'Zm9vYmFy' ); // 'foobar'
const attempt = ( fn, ...args ) => {
try {
return fn( ...args );
} catch ( e ) {
return e instanceof Error ? e : new Error( e );
}
};
let elements = attempt( function ( selector ) {
return document.querySelectorAll( selector );
}, '>_>' );
if ( elements instanceof Error ) elements = []; // elements = []
function average( ...nums ) {
return nums.reduce( ( acc, val ) => acc + val, 0 ) / nums.length;
}
average( ...[ 1, 2, 3 ] ); // 2
average( 1, 2, 3 ); // 2
function averageBy( arr, fn ) {
return arr
.map( typeof fn === 'function' ? fn : val => val[ fn ] )
.reduce( ( acc, val ) => acc + val, 0 ) / arr.length;
}
averageBy( [ { n: 4 }, { n: 2 }, { n: 8 }, { n: 6 } ], o => o.n ); // 5
averageBy( [ { n: 4 }, { n: 2 }, { n: 8 }, { n: 6 } ], 'n' ); // 5
const bifurcate = ( arr, filter ) =>
arr.reduce( ( acc, val, i ) => ( acc[ filter[ i ] ? 0 : 1 ].push( val ), acc ), [
[],
[],
] );
bifurcate( [ 'beep', 'boop', 'foo', 'bar' ], [ true, true, false, true ] );
// [ ['beep', 'boop', 'bar'], ['foo'] ]
function bind( fn, context, ...args ) {
return function () {
return fn.apply( context, args.concat( ...arguments ) );
};
}
function bifurcateBy( arr, fn ) {
return arr.reduce( ( acc, val, i ) => ( acc[ fn( val, i ) ? 0 : 1 ].push( val ), acc ), [
[],
[],
] );
}
bifurcateBy( [ 'beep', 'boop', 'foo', 'bar' ], x => x[ 0 ] === 'b' );
// [ ['beep', 'boop', 'bar'], ['foo'] ]
const binary = fn => ( a, b ) => fn( a, b );
[ '2', '1', '0' ].map( binary( Math.max ) ); // [2, 1, 2]
const binarySearch = ( arr, item ) => {
let l = 0,
r = arr.length - 1;
while ( l <= r ) {
const mid = Math.floor( ( l + r ) / 2 );
const guess = arr[ mid ];
if ( guess === item ) return mid;
if ( guess > item ) r = mid - 1;
else l = mid + 1;
}
return -1;
};
binarySearch( [ 1, 2, 3, 4, 5 ], 1 ); // 0
binarySearch( [ 1, 2, 3, 4, 5 ], 5 ); // 4
binarySearch( [ 1, 2, 3, 4, 5 ], 6 ); // -1
const bind = ( fn, context, ...boundArgs ) => ( ...args ) =>
fn.apply( context, [ ...boundArgs, ...args ] );
function greet( greeting, punctuation ) {
return greeting + ' ' + this.user + punctuation;
}
const freddy = { user: 'fred' };
const freddyBound = bind( greet, freddy );
console.log( freddyBound( 'hi', '!' ) ); // 'hi fred!'
function bindAll( obj, ...fns ) {
return fns.forEach(
fn => (
( f = obj[ fn ] ),
( obj[ fn ] = function () {
return f.apply( obj );
} )
)
);
}
let view = {
label: 'docs',
click: function () {
console.log( 'clicked ' + this.label );
}
};
bindAll( view, 'click' );
document.body.addEventListener( 'click', view.click );
// Log 'clicked docs' when clicked.
function bindKey( context, fn, ...boundArgs ) {
return ( ...args ) => context[ fn ].apply( context, [ ...boundArgs, ...args ] );
}
const freddy = {
user: 'fred',
greet: function ( greeting, punctuation ) {
return greeting + ' ' + this.user + punctuation;
}
};
const freddyBound = bindKey( freddy, 'greet' );
console.log( freddyBound( 'hi', '!' ) ); // 'hi fred!'
function binomialCoefficient( n, k ) {
if ( Number.isNaN( n ) || Number.isNaN( k ) )
return NaN;
if ( k < 0 || k > n )
return 0;
if ( k === 0 || k === n )
return 1;
if ( k === 1 || k === n - 1 )
return n;
if ( n - k < k )
k = n - k;
let res = n;
for ( let j = 2; j <= k; j++ )
res *= ( n - j + 1 ) / j;
return Math.round( res );
}
binomialCoefficient( 8, 2 ); // 28
function both( f, g ) {
return ( ...args ) => f( ...args ) && g( ...args );
}
function btoa( str ) {
return new Buffer( str, 'binary' ).toString( 'base64' );
}
function isEven( num ) {
return num % 2 === 0;
}
const isPositive = num => num > 0;
const isPositiveEven = both( isEven, isPositive );
isPositiveEven( 4 ); // true
isPositiveEven( -2 ); // false
const HSBToRGB = ( h, s, b ) => {
s /= 100;
b /= 100;
const k = ( n ) => ( n + h / 60 ) % 6;
const f = ( n ) => b * ( 1 - s * Math.max( 0, Math.min( k( n ), 4 - k( n ), 1 ) ) );
return [ 255 * f( 5 ), 255 * f( 3 ), 255 * f( 1 ) ];
};
HSBToRGB( 18, 81, 99 ); // [252.45, 109.31084999999996, 47.965499999999984]
const HSLToRGB = ( h, s, l ) => {
s /= 100;
l /= 100;
const k = n => ( n + h / 30 ) % 12;
const a = s * Math.min( l, 1 - l );
const f = n =>
l - a * Math.max( -1, Math.min( k( n ) - 3, Math.min( 9 - k( n ), 1 ) ) );
return [ 255 * f( 0 ), 255 * f( 8 ), 255 * f( 4 ) ];
};
HSLToRGB( 13, 100, 11 ); // [56.1, 12.155, 0]
const fs = require( 'fs' );
const JSONToFile = ( obj, filename ) =>
fs.writeFileSync( `${ filename }.json`, JSON.stringify( obj, null, 2 ) );
JSONToFile( { test: 'is passed' }, 'testJsonFile' );
// writes the object to 'testJsonFile.json'
const JSONtoCSV = ( arr, columns, delimiter = ',' ) =>
[
columns.join( delimiter ),
...arr.map( obj =>
columns.reduce(
( acc, key ) =>
`${ acc }${ !acc.length ? '' : delimiter }"${ !obj[ key ] ? '' : obj[ key ] }"`,
''
)
),
].join( '\n' );
JSONtoCSV(
[ { a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 } ],
[ 'a', 'b' ]
); // 'a,b\n"1","2"\n"3","4"\n"6",""\n"","7"'
JSONtoCSV(
[ { a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 } ],
[ 'a', 'b' ],
';'
); // 'a;b\n"1";"2"\n"3";"4"\n"6";""\n"";"7"'
const RGBToHSB = ( r, g, b ) => {
r /= 255;
g /= 255;
b /= 255;
const v = Math.max( r, g, b ),
n = v - Math.min( r, g, b );
const h =
n === 0 ? 0 : n && v === r ? ( g - b ) / n : v === g ? 2 + ( b - r ) / n : 4 + ( r - g ) / n;
return [ 60 * ( h < 0 ? h + 6 : h ), v && ( n / v ) * 100, v * 100 ];
};
RGBToHSB( 252, 111, 48 );
// [18.529411764705856, 80.95238095238095, 98.82352941176471]
const RGBToHSL = ( r, g, b ) => {
r /= 255;
g /= 255;
b /= 255;
const l = Math.max( r, g, b );
const s = l - Math.min( r, g, b );
const h = s
? l === r
? ( g - b ) / s
: l === g
? 2 + ( b - r ) / s
: 4 + ( r - g ) / s
: 0;
return [
60 * h < 0 ? 60 * h + 360 : 60 * h,
100 * ( s ? ( l <= 0.5 ? s / ( 2 * l - s ) : s / ( 2 - ( 2 * l - s ) ) ) : 0 ),
( 100 * ( 2 * l - s ) ) / 2,
];
};
RGBToHSL( 45, 23, 11 ); // [21.17647, 60.71428, 10.98039]
const RGBToHex = ( r, g, b ) =>
( ( r << 16 ) + ( g << 8 ) + b ).toString( 16 ).padStart( 6, '0' );
RGBToHex( 255, 165, 1 ); // 'ffa501'
function URLJoin( ...args ) {
return args
.join( '/' )
.replace( /[\/]+/g, '/' )
.replace( /^(.+):\//, '$1://' )
.replace( /^file:/, 'file:/' )
.replace( /\/(\?|&|#[^!])/g, '$1' )
.replace( /\?/g, '&' )
.replace( '&', '?' );
}
URLJoin( 'http://www.google.com', 'a', '/b/cd', '?foo=123', '?bar=foo' );
// 'http://www.google.com/a/b/cd?foo=123&bar=foo'
function UUIDGeneratorBrowser() {
return ( [ 1e7 ] + -1e3 + -4e3 + -8e3 + -1e11 ).replace( /[018]/g, c => (
c ^
( crypto.getRandomValues( new Uint8Array( 1 ) )[ 0 ] & ( 15 >> ( c / 4 ) ) )
).toString( 16 )
);
}
UUIDGeneratorBrowser(); // '7982fcfe-5721-4632-bede-6000885be57d'
const crypto = require( 'crypto' );
function UUIDGeneratorNode() {
return ( [ 1e7 ] + -1e3 + -4e3 + -8e3 + -1e11 ).replace( /[018]/g, c => ( c ^ ( crypto.randomBytes( 1 )[ 0 ] & ( 15 >> ( c / 4 ) ) ) ).toString( 16 )
);
}
UUIDGeneratorNode(); // '79c7c136-60ee-40a2-beb2-856f1feabefc'
function accumulate( ...nums ) {
return nums.reduce( ( acc, n ) => [ ...acc, n + +acc.slice( -1 ) ], [] );
}
accumulate( 1, 2, 3, 4 ); // [1, 3, 6, 10]
accumulate( ...[ 1, 2, 3, 4 ] ); // [1, 3, 6, 10]
function addClass( el, className ) {
return el.classList.add( className );
}
addClass( document.querySelector( 'p' ), 'special' );
// The paragraph will now have the 'special' class
function addDaysToDate( date, n ) {
const d = new Date( date );
d.setDate( d.getDate() + n );
return d.toISOString().split( 'T' )[ 0 ];
}
addDaysToDate( '2020-10-15', 10 ); // '2020-10-25'
addDaysToDate( '2020-10-15', -10 ); // '2020-10-05'
function addEventListenerAll( targets, type, listener, options, useCapture ) {
targets.forEach( target => target.addEventListener( type, listener, options, useCapture )
);
}
addEventListenerAll( document.querySelectorAll( 'a' ), 'click', () =>
console.log( 'Clicked a link' )
);
// Logs 'Clicked a link' whenever any anchor element is clicked
function addMinutesToDate( date, n ) {
const d = new Date( date );
d.setTime( d.getTime() + n * 60000 );
return d.toISOString().split( '.' )[ 0 ].replace( 'T', ' ' );
}
addMinutesToDate( '2020-10-19 12:00:00', 10 ); // '2020-10-19 12:10:00'
addMinutesToDate( '2020-10-19', -10 ); // '2020-10-18 23:50:00'
function addMultipleListeners( el, types, listener, options, useCapture ) {
types.forEach( type => el.addEventListener( type, listener, options, useCapture )
);
}
addMultipleListeners(
document.querySelector( '.my-element' ),
[ 'click', 'mousedown' ],
() => { console.log( 'hello!' ) }
);
function addStyles( el, styles ) {
return Object.assign( el.style, styles );
}
addStyles( document.getElementById( 'my-element' ), {
background: 'red',
color: '#ffff00',
fontSize: '3rem'
} );
function addWeekDays( startDate, count ) {
return Array.from( { length: count } ).reduce( date => {
date = new Date( date.setDate( date.getDate() + 1 ) );
if ( date.getDay() % 6 === 0 )
date = new Date( date.setDate( date.getDate() + ( date.getDay() / 6 + 1 ) ) );
return date;
}, startDate );
}
addWeekDays( new Date( 'Oct 09, 2020' ), 5 ); // 'Oct 16, 2020'
addWeekDays( new Date( 'Oct 12, 2020' ), 5 ); // 'Oct 19, 2020'
function all( arr, fn = Boolean ) {
return arr.every( fn );
}
all( [ 4, 2, 3 ], x => x > 1 ); // true
all( [ 1, 2, 3 ] ); // true
function allEqual( arr ) {
return arr.every( val => val === arr[ 0 ] );
}
allEqual( [ 1, 2, 3, 4, 5, 6 ] ); // false
allEqual( [ 1, 1, 1, 1 ] ); // true
function allEqualBy( arr, fn ) {
const eql = fn( arr[ 0 ] );
return arr.every( val => fn( val ) === eql );
}
allEqualBy( [ 1.1, 1.2, 1.3 ], Math.round ); // true
allEqualBy( [ 1.1, 1.3, 1.6 ], Math.round ); // false
function allUnique( arr ) {
return arr.length === new Set( arr ).size;
}
allUnique( [ 1, 2, 3, 4 ] ); // true
allUnique( [ 1, 1, 2, 3 ] ); // false
function allUniqueBy( arr, fn ) {
return arr.length === new Set( arr.map( fn ) ).size;
}
allUniqueBy( [ 1.2, 2.4, 2.9 ], Math.round ); // true
allUniqueBy( [ 1.2, 2.3, 2.4 ], Math.round ); // false
function and( a, b ) {
return a && b;
}
and( true, true ); // true
and( true, false ); // false
and( false, false ); // false
const any = ( arr, fn = Boolean ) => arr.some( fn );
any( [ 0, 1, 2, 0 ], x => x >= 2 ); // true
any( [ 0, 0, 1, 0 ] ); // true
function aperture( n, arr ) {
return n > arr.length
? []
: arr.slice( n - 1 ).map( ( v, i ) => arr.slice( i, i + n ) );
}
aperture( 2, [ 1, 2, 3, 4 ] ); // [[1, 2], [2, 3], [3, 4]]
aperture( 3, [ 1, 2, 3, 4 ] ); // [[1, 2, 3], [2, 3, 4]]
aperture( 5, [ 1, 2, 3, 4 ] ); // []
function approximatelyEqual( v1, v2, epsilon = 0.001 ) {
return Math.abs( v1 - v2 ) < epsilon;
}
approximatelyEqual( Math.PI / 2.0, 1.5708 ); // true
function arithmeticProgression( n, lim ) {
return Array.from( { length: Math.ceil( lim / n ) }, ( _, i ) => ( i + 1 ) * n );
}
arithmeticProgression( 5, 25 ); // [5, 10, 15, 20, 25]
function arrayToCSV( arr, delimiter = ',' ) {
return arr
.map( v => v.map( x => ( isNaN( x ) ? `"${ x.replace( /"/g, '""' ) }"` : x ) ).join( delimiter )
)
.join( '\n' );
}
arrayToCSV( [ [ 'a', 'b' ], [ 'c', 'd' ] ] ); // '"a","b"\n"c","d"'
arrayToCSV( [ [ 'a', 'b' ], [ 'c', 'd' ] ], ';' ); // '"a";"b"\n"c";"d"'
arrayToCSV( [ [ 'a', '"b" great' ], [ 'c', 3.1415 ] ] );
// '"a","""b"" great"\n"c",3.1415'
function arrayToHTMLList( arr, listID ) {
return document.querySelector( `#${ listID }` ).innerHTML += arr
.map( item => `<li>${ item }</li>` )
.join( '' );
}
arrayToHTMLList( [ 'item 1', 'item 2' ], 'myListID' );
function ary( fn, n ) {
return ( ...args ) => fn( ...args.slice( 0, n ) );
}
const firstTwoMax = ary( Math.max, 2 );
[ [ 2, 6, 'a' ], [ 6, 4, 8 ], [ 10 ] ].map( x => firstTwoMax( ...x ) ); // [6, 6, 10]
function assertValidKeys( obj, keys ) {
return Object.keys( obj ).every( key => keys.includes( key ) );
}
assertValidKeys( { id: 10, name: 'apple' }, [ 'id', 'name' ] ); // true
assertValidKeys( { id: 10, name: 'apple' }, [ 'id', 'type' ] ); // false
function atob( str ) {
return Buffer.from( str, 'base64' ).toString( 'binary' );
}
atob( 'Zm9vYmFy' ); // 'foobar'
function attempt( fn, ...args ) {
try {
return fn( ...args );
} catch ( e ) {
return e instanceof Error ? e : new Error( e );
}
}
let elements = attempt( function ( selector ) {
return document.querySelectorAll( selector );
}, '>_>' );
if ( elements instanceof Error ) elements = []; // elements = []
function average( ...nums ) {
return nums.reduce( ( acc, val ) => acc + val, 0 ) / nums.length;
}
average( ...[ 1, 2, 3 ] ); // 2
average( 1, 2, 3 ); // 2
function averageBy( arr, fn ) {
return arr
.map( typeof fn === 'function' ? fn : val => val[ fn ] )
.reduce( ( acc, val ) => acc + val, 0 ) / arr.length;
}
averageBy( [ { n: 4 }, { n: 2 }, { n: 8 }, { n: 6 } ], o => o.n ); // 5
averageBy( [ { n: 4 }, { n: 2 }, { n: 8 }, { n: 6 } ], 'n' ); // 5
function bifurcate( arr, filter ) {
return arr.reduce( ( acc, val, i ) => ( acc[ filter[ i ] ? 0 : 1 ].push( val ), acc ), [
[],
[],
] );
}
bifurcate( [ 'beep', 'boop', 'foo', 'bar' ], [ true, true, false, true ] );
// [ ['beep', 'boop', 'bar'], ['foo'] ]
function bifurcateBy( arr, fn ) {
return arr.reduce( ( acc, val, i ) => ( acc[ fn( val, i ) ? 0 : 1 ].push( val ), acc ), [
[],
[],
] );
}
bifurcateBy( [ 'beep', 'boop', 'foo', 'bar' ], x => x[ 0 ] === 'b' );
// [ ['beep', 'boop', 'bar'], ['foo'] ]
const binary = fn => ( a, b ) => fn( a, b );
[ '2', '1', '0' ].map( binary( Math.max ) ); // [2, 1, 2]
function binarySearch( arr, item ) {
let l = 0, r = arr.length - 1;
while ( l <= r ) {
const mid = Math.floor( ( l + r ) / 2 );
const guess = arr[ mid ];
if ( guess === item )
return mid;
if ( guess > item )
r = mid - 1;
else
l = mid + 1;
}
return -1;
}
binarySearch( [ 1, 2, 3, 4, 5 ], 1 ); // 0
binarySearch( [ 1, 2, 3, 4, 5 ], 5 ); // 4
binarySearch( [ 1, 2, 3, 4, 5 ], 6 ); // -1
function bind( fn, context, ...boundArgs ) {
return ( ...args ) => fn.apply( context, [ ...boundArgs, ...args ] );
}
function greet( greeting, punctuation ) {
return greeting + ' ' + this.user + punctuation;
}
const freddy = { user: 'fred' };
const freddyBound = bind( greet, freddy );
console.log( freddyBound( 'hi', '!' ) ); // 'hi fred!'
const bindAll = ( obj, ...fns ) =>
fns.forEach(
fn => (
( f = obj[ fn ] ),
( obj[ fn ] = function () {
return f.apply( obj );
} )
)
);
let view = {
label: 'docs',
click: function () {
console.log( 'clicked ' + this.label );
}
};
bindAll( view, 'click' );
document.body.addEventListener( 'click', view.click );
// Log 'clicked docs' when clicked.
function bindKey( context, fn, ...boundArgs ) {
return ( ...args ) => context[ fn ].apply( context, [ ...boundArgs, ...args ] );
}
const freddy = {
user: 'fred',
greet: function ( greeting, punctuation ) {
return greeting + ' ' + this.user + punctuation;
}
};
const freddyBound = bindKey( freddy, 'greet' );
console.log( freddyBound( 'hi', '!' ) ); // 'hi fred!'
const binomialCoefficient = ( n, k ) => {
if ( Number.isNaN( n ) || Number.isNaN( k ) ) return NaN;
if ( k < 0 || k > n ) return 0;
if ( k === 0 || k === n ) return 1;
if ( k === 1 || k === n - 1 ) return n;
if ( n - k < k ) k = n - k;
let res = n;
for ( let j = 2; j <= k; j++ ) res *= ( n - j + 1 ) / j;
return Math.round( res );
};
binomialCoefficient( 8, 2 ); // 28
const both = ( f, g ) => ( ...args ) => f( ...args ) && g( ...args );
function isEven( num ) {
return num % 2 === 0;
}
function isPositive( num ) {
return num > 0;
}
const isPositiveEven = both( isEven, isPositive );
isPositiveEven( 4 ); // true
isPositiveEven( -2 ); // false
function btoa( str ) {
return Buffer.from( str, 'binary' ).toString( 'base64' );
}
btoa( 'foobar' ); // 'Zm9vYmFy'
function bubbleSort( arr ) {
let swapped = false;
const a = [ ...arr ];
for ( let i = 1; i < a.length; i++ ) {
swapped = false;
for ( let j = 0; j < a.length - i; j++ ) {
if ( a[ j + 1 ] < a[ j ] ) {
[ a[ j ], a[ j + 1 ] ] = [ a[ j + 1 ], a[ j ] ];
swapped = true;
}
}
if ( !swapped )
return a;
}
return a;
}
bubbleSort( [ 2, 1, 4, 3 ] ); // [1, 2, 3, 4]
function bucketSort( arr, size = 5 ) {
const min = Math.min( ...arr );
const max = Math.max( ...arr );
const buckets = Array.from(
{ length: Math.floor( ( max - min ) / size ) + 1 },
() => []
);
arr.forEach( val => {
buckets[ Math.floor( ( val - min ) / size ) ].push( val );
} );
return buckets.reduce( ( acc, b ) => [ ...acc, ...b.sort( ( a, b ) => a - b ) ], [] );
}
bucketSort( [ 6, 3, 4, 1 ] ); // [1, 3, 4, 6]
function byteSize( str ) {
return new Blob( [ str ] ).size;
}
byteSize( '😀' ); // 4
byteSize( 'Hello World' ); // 11
const caesarCipher = ( str, shift, decrypt = false ) => {
const s = decrypt ? ( 26 - shift ) % 26 : shift;
const n = s > 0 ? s : 26 + ( s % 26 );
return [ ...str ]
.map( ( l, i ) => {
const c = str.charCodeAt( i );
if ( c >= 65 && c <= 90 )
return String.fromCharCode( ( ( c - 65 + n ) % 26 ) + 65 );
if ( c >= 97 && c <= 122 )
return String.fromCharCode( ( ( c - 97 + n ) % 26 ) + 97 );
return l;
} )
.join( '' );
};
caesarCipher( 'Hello World!', -3 ); // 'Ebiil Tloia!'
caesarCipher( 'Ebiil Tloia!', 23, true ); // 'Hello World!'
function call( key, ...args ) {
return context => context[ key ]( ...args );
}
Promise.resolve( [ 1, 2, 3 ] )
.then( call( 'map', x => 2 * x ) )
.then( console.log ); // [ 2, 4, 6 ]
const map = call.bind( null, 'map' );
Promise.resolve( [ 1, 2, 3 ] )
.then( map( x => 2 * x ) )
.then( console.log ); // [ 2, 4, 6 ]
const capitalize = ( [ first, ...rest ], lowerRest = false ) =>
first.toUpperCase() +
( lowerRest ? rest.join( '' ).toLowerCase() : rest.join( '' ) );
capitalize( 'fooBar' ); // 'FooBar'
capitalize( 'fooBar', true ); // 'Foobar'
const capitalizeEveryWord = str =>
str.replace( /\b[a-z]/g, char => char.toUpperCase() );
capitalizeEveryWord( 'hello world!' ); // 'Hello World!'
const cartesianProduct = ( a, b ) =>
a.reduce( ( p, x ) => [ ...p, ...b.map( y => [ x, y ] ) ], [] );
cartesianProduct( [ 'x', 'y' ], [ 1, 2 ] );
// [['x', 1], ['x', 2], ['y', 1], ['y', 2]]
const castArray = val => ( Array.isArray( val ) ? val : [ val ] );
castArray( 'foo' ); // ['foo']
castArray( [ 1 ] ); // [1]
const celsiusToFahrenheit = degrees => 1.8 * degrees + 32;
celsiusToFahrenheit( 33 ); // 91.4
const chainAsync = fns => {
let curr = 0;
const last = fns[ fns.length - 1 ];
const next = () => {
const fn = fns[ curr++ ];
fn === last ? fn() : fn( next );
};
next();
};
chainAsync( [
next => {
console.log( '0 seconds' );
setTimeout( next, 1000 );
},
next => {
console.log( '1 second' );
setTimeout( next, 1000 );
},
() => {
console.log( '2 second' );
}
] );
const changeLightness = ( delta, hslStr ) => {
const [ hue, saturation, lightness ] = hslStr.match( /\d+/g ).map( Number );
const newLightness = Math.max(
0,
Math.min( 100, lightness + parseFloat( delta ) )
);
return `hsl(${ hue }, ${ saturation }%, ${ newLightness }%)`;
};
changeLightness( 10, 'hsl(330, 50%, 50%)' ); // 'hsl(330, 50%, 60%)'
changeLightness( -10, 'hsl(330, 50%, 50%)' ); // 'hsl(330, 50%, 40%)'
const checkProp = ( predicate, prop ) => obj => !!predicate( obj[ prop ] );
const lengthIs4 = checkProp( l => l === 4, 'length' );
lengthIs4( [] ); // false
lengthIs4( [ 1, 2, 3, 4 ] ); // true
lengthIs4( new Set( [ 1, 2, 3, 4 ] ) ); // false (Set uses Size, not length)
const session = { user: {} };
const validUserSession = checkProp( u => u.active && !u.disabled, 'user' );
validUserSession( session ); // false
session.user.active = true;
validUserSession( session ); // true
const noLength = checkProp( l => l === undefined, 'length' );
noLength( [] ); // false
noLength( {} ); // true
noLength( new Set() ); // true
function chunk( arr, size ) {
return Array.from( { length: Math.ceil( arr.length / size ) }, ( v, i ) => arr.slice( i * size, i * size + size )
);
}
chunk( [ 1, 2, 3, 4, 5 ], 2 ); // [[1, 2], [3, 4], [5]]
function chunkIntoN( arr, n ) {
const size = Math.ceil( arr.length / n );
return Array.from( { length: n }, ( v, i ) => arr.slice( i * size, i * size + size )
);
}
chunkIntoN( [ 1, 2, 3, 4, 5, 6, 7 ], 4 ); // [[1, 2], [3, 4], [5, 6], [7]]
const chunkify = function* ( itr, size ) {
let chunk = [];
for ( const v of itr ) {
chunk.push( v );
if ( chunk.length === size ) {
yield chunk;
chunk = [];
}
}
if ( chunk.length ) yield chunk;
};
const x = new Set( [ 1, 2, 1, 3, 4, 1, 2, 5 ] );
[ ...chunkify( x, 2 ) ]; // [[1, 2], [3, 4], [5]]
const clampNumber = ( num, a, b ) =>
Math.max( Math.min( num, Math.max( a, b ) ), Math.min( a, b ) );
clampNumber( 2, 3, 5 ); // 3
clampNumber( 1, -1, -5 ); // -1
const cloneRegExp = regExp => new RegExp( regExp.source, regExp.flags );
const regExp = /lorem ipsum/gi;
const regExp2 = cloneRegExp( regExp ); // regExp !== regExp2
const coalesce = ( ...args ) => args.find( v => ![ undefined, null ].includes( v ) );
coalesce( null, undefined, '', NaN, 'Waldo' ); // ''
const coalesceFactory = valid => ( ...args ) => args.find( valid );
const customCoalesce = coalesceFactory(
v => ![ null, undefined, '', NaN ].includes( v )
);
customCoalesce( undefined, null, NaN, '', 'Waldo' ); // 'Waldo'
const collectInto = fn => ( ...args ) => fn( args );
const Pall = collectInto( Promise.all.bind( Promise ) );
let p1 = Promise.resolve( 1 );
let p2 = Promise.resolve( 2 );
let p3 = new Promise( resolve => setTimeout( resolve, 2000, 3 ) );
Pall( p1, p2, p3 ).then( console.log ); // [1, 2, 3] (after about 2 seconds)
const colorize = ( ...args ) => ( {
black: `\x1b[30m${ args.join( ' ' ) }`,
red: `\x1b[31m${ args.join( ' ' ) }`,
green: `\x1b[32m${ args.join( ' ' ) }`,
yellow: `\x1b[33m${ args.join( ' ' ) }`,
blue: `\x1b[34m${ args.join( ' ' ) }`,
magenta: `\x1b[35m${ args.join( ' ' ) }`,
cyan: `\x1b[36m${ args.join( ' ' ) }`,
white: `\x1b[37m${ args.join( ' ' ) }`,
bgBlack: `\x1b[40m${ args.join( ' ' ) }\x1b[0m`,
bgRed: `\x1b[41m${ args.join( ' ' ) }\x1b[0m`,
bgGreen: `\x1b[42m${ args.join( ' ' ) }\x1b[0m`,
bgYellow: `\x1b[43m${ args.join( ' ' ) }\x1b[0m`,
bgBlue: `\x1b[44m${ args.join( ' ' ) }\x1b[0m`,
bgMagenta: `\x1b[45m${ args.join( ' ' ) }\x1b[0m`,
bgCyan: `\x1b[46m${ args.join( ' ' ) }\x1b[0m`,
bgWhite: `\x1b[47m${ args.join( ' ' ) }\x1b[0m`
} );
console.log( colorize( 'foo' ).red ); // 'foo' (red letters)
console.log( colorize( 'foo', 'bar' ).bgBlue ); // 'foo bar' (blue background)
console.log( colorize( colorize( 'foo' ).yellow, colorize( 'foo' ).green ).bgWhite );
// 'foo bar' (first word in yellow letters, second word in green letters, white background for both)
const combine = ( a, b, prop ) =>
Object.values(
[ ...a, ...b ].reduce( ( acc, v ) => {
if ( v[ prop ] )
acc[ v[ prop ] ] = acc[ v[ prop ] ]
? { ...acc[ v[ prop ] ], ...v }
: { ...v };
return acc;
}, {} )
);
const x = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Maria' }
];
const y = [
{ id: 1, age: 28 },
{ id: 3, age: 26 },
{ age: 3 }
];
combine( x, y, 'id' );
// [
// { id: 1, name: 'John', age: 28 },
// { id: 2, name: 'Maria' },
// { id: 3, age: 26 }
// ]
function compact( arr ) {
return arr.filter( Boolean );
}
compact( [ 0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34 ] );
// [ 1, 2, 3, 'a', 's', 34 ]
function compactObject( val ) {
const data = Array.isArray( val ) ? val.filter( Boolean ) : val;
return Object.keys( data ).reduce(
( acc, key ) => {
const value = data[ key ];
if ( Boolean( value ) )
acc[ key ] = typeof value === 'object' ? compactObject( value ) : value;
return acc;
},
Array.isArray( val ) ? [] : {}
);
}
const obj = {
a: null,
b: false,
c: true,
d: 0,
e: 1,
f: '',
g: 'a',
h: [ null, false, '', true, 1, 'a' ],
i: { j: 0, k: false, l: 'a' }
};
compactObject( obj );
// { c: true, e: 1, g: 'a', h: [ true, 1, 'a' ], i: { l: 'a' } }
function compactWhitespace( str ) {
return str.replace( /\s{2,}/g, ' ' );
}
compactWhitespace( 'Lorem Ipsum' ); // 'Lorem Ipsum'
compactWhitespace( 'Lorem \n Ipsum' ); // 'Lorem Ipsum'
function complement( fn ) {
return ( ...args ) => {
return !fn( ...args );
};
}
function isEven( num ) {
return num % 2 === 0;
}
const isOdd = complement( isEven );
isOdd( 2 ); // false
isOdd( 3 ); // true
function compose( ...fns ) {
return fns.reduce( ( f, g ) => ( ...args ) => f( g( ...args ) ) );
}
const add5 = x => x + 5;
const multiply = ( x, y ) => x * y;
const multiplyAndAdd5 = compose(
add5,
multiply
);
multiplyAndAdd5( 5, 2 ); // 15
const composeRight = ( ...fns ) =>
fns.reduce( ( f, g ) => ( ...args ) => g( f( ...args ) ) );
const add = ( x, y ) => x + y;
const square = x => x * x;
const addAndSquare = composeRight( add, square );
addAndSquare( 1, 2 ); // 9
const containsWhitespace = str => /\s/.test( str );
containsWhitespace( 'lorem' ); // false
containsWhitespace( 'lorem ipsum' ); // true
const converge = ( converger, fns ) => ( ...args ) =>
converger( ...fns.map( fn => fn.apply( null, args ) ) );
const average = converge( ( a, b ) => a / b, [
arr => arr.reduce( ( a, v ) => a + v, 0 ),
arr => arr.length
] );
average( [ 1, 2, 3, 4, 5, 6, 7 ] ); // 4
const copySign = ( x, y ) => Math.sign( x ) === Math.sign( y ) ? x : -x;
copySign( 2, 3 ); // 2
copySign( 2, -3 ); // -2
copySign( -2, 3 ); // 2
copySign( -2, -3 ); // -2
const copyToClipboard = str => {
const el = document.createElement( 'textarea' );
el.value = str;
el.setAttribute( 'readonly', '' );
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild( el );
const selected =
document.getSelection().rangeCount > 0
? document.getSelection().getRangeAt( 0 )
: false;
el.select();
document.execCommand( 'copy' );
document.body.removeChild( el );
if ( selected ) {
document.getSelection().removeAllRanges();
document.getSelection().addRange( selected );
}
};
copyToClipboard( 'Lorem ipsum' ); // 'Lorem ipsum' copied to clipboard.
const countBy = ( arr, fn ) =>
arr.map( typeof fn === 'function' ? fn : val => val[ fn ] ).reduce( ( acc, val ) => {
acc[ val ] = ( acc[ val ] || 0 ) + 1;
return acc;
}, {} );
countBy( [ 6.1, 4.2, 6.3 ], Math.floor ); // {4: 1, 6: 2}
countBy( [ 'one', 'two', 'three' ], 'length' ); // {3: 2, 5: 1}
countBy( [ { count: 5 }, { count: 10 }, { count: 5 } ], x => x.count )
// {5: 2, 10: 1}
const countOccurrences = ( arr, val ) =>
arr.reduce( ( a, v ) => ( v === val ? a + 1 : a ), 0 );
countOccurrences( [ 1, 1, 2, 1, 2, 3 ], 1 ); // 3
const countSubstrings = ( str, searchValue ) => {
let count = 0,
i = 0;
while ( true ) {
const r = str.indexOf( searchValue, i );
if ( r !== -1 ) [ count, i ] = [ count + 1, r + 1 ];
else return count;
}
};
countSubstrings( 'tiktok tok tok tik tok tik', 'tik' ); // 3
countSubstrings( 'tutut tut tut', 'tut' ); // 4
const countWeekDaysBetween = ( startDate, endDate ) =>
Array
.from( { length: ( endDate - startDate ) / ( 1000 * 3600 * 24 ) } )
.reduce( count => {
if ( startDate.getDay() % 6 !== 0 ) count++;
startDate = new Date( startDate.setDate( startDate.getDate() + 1 ) );
return count;
}, 0 );
countWeekDaysBetween( new Date( 'Oct 05, 2020' ), new Date( 'Oct 06, 2020' ) ); // 1
countWeekDaysBetween( new Date( 'Oct 05, 2020' ), new Date( 'Oct 14, 2020' ) ); // 7
const counter = ( selector, start, end, step = 1, duration = 2000 ) => {
let current = start,
_step = ( end - start ) * step < 0 ? -step : step,
timer = setInterval( () => {
current += _step;
document.querySelector( selector ).innerHTML = current;
if ( current >= end ) document.querySelector( selector ).innerHTML = end;
if ( current >= end ) clearInterval( timer );
}, Math.abs( Math.floor( duration / ( end - start ) ) ) );
return timer;
};
counter( '#my-id', 1, 1000, 5, 2000 );
// Creates a 2-second timer for the element with id="my-id"
const fs = require( 'fs' );
function createDirIfNotExists( dir ) {
return ( !fs.existsSync( dir ) ? fs.mkdirSync( dir ) : undefined );
}
createDirIfNotExists( 'test' );
// creates the directory 'test', if it doesn't exist
const createElement = str => {
const el = document.createElement( 'div' );
el.innerHTML = str;
return el.firstElementChild;
};
const el = createElement(
`<div class="container">
<p>Hello!</p>
</div>`
);
console.log( el.className ); // 'container'
const handler = data => console.log( data );
const hub = createEventHub();
let increment = 0;
// Subscribe: listen for different types of events
hub.on( 'message', handler );
hub.on( 'message', () => console.log( 'Message event fired' ) );
hub.on( 'increment', () => increment++ );
// Publish: emit events to invoke all handlers subscribed to them, passing the data to them as an argument
hub.emit( 'message', 'hello world' ); // logs 'hello world' and 'Message event fired'
hub.emit( 'message', { hello: 'world' } ); // logs the object and 'Message event fired'
hub.emit( 'increment' ); // `increment` variable is now 1
// Unsubscribe: stop a specific handler from listening to the 'message' event
hub.off( 'message', handler );
function currentURL() {
return window.location.href;
}
currentURL(); // 'https://www.google.com/'
function curry( fn, arity = fn.length, ...args ) {
return arity <= args.length ? fn( ...args ) : curry.bind( null, fn, arity, ...args );
}
curry( Math.pow )( 2 )( 10 ); // 1024
curry( Math.min, 3 )( 10 )( 50 )( 2 ); // 2
function* cycleGenerator( arr ) {
let i = 0;
while ( true ) {
yield arr[ i % arr.length ];
i++;
}
}
const binaryCycle = cycleGenerator( [ 0, 1 ] );
binaryCycle.next(); // { value: 0, done: false }
binaryCycle.next(); // { value: 1, done: false }
binaryCycle.next(); // { value: 0, done: false }
binaryCycle.next(); // { value: 1, done: false }
function* dateRangeGenerator( start, end, step = 1 ) {
let d = start;
while ( d < end ) {
yield new Date( d );
d.setDate( d.getDate() + step );
}
}
[ ...dateRangeGenerator( new Date( '2021-06-01' ), new Date( '2021-06-04' ) ) ];
// [ 2021-06-01, 2021-06-02, 2021-06-03 ]
function dayName( date, locale ) {
return date.toLocaleDateString( locale, { weekday: 'long' } );
}
dayName( new Date() ); // 'Saturday'
dayName( new Date( '09/23/2020' ), 'de-DE' ); // 'Samstag'
const dayOfYear = date =>
Math.floor( ( date - new Date( date.getFullYear(), 0, 0 ) ) / 1000 / 60 / 60 / 24 );
dayOfYear( new Date() ); // 272
function daysAgo( n ) {
let d = new Date();
d.setDate( d.getDate() - Math.abs( n ) );
return d.toISOString().split( 'T' )[ 0 ];
}
daysAgo( 20 ); // 2020-09-16 (if current date is 2020-10-06)
function daysFromNow( n ) {
let d = new Date();
d.setDate( d.getDate() + Math.abs( n ) );
return d.toISOString().split( 'T' )[ 0 ];
}
daysFromNow( 5 ); // 2020-10-13 (if current date is 2020-10-08)
function daysInMonth( year, month ) {
return new Date( year, month, 0 ).getDate();
}
daysInMonth( 2020, 12 )); // 31
daysInMonth( 2024, 2 )); // 29
function debounce( fn, ms = 0 ) {
let timeoutId;
return function ( ...args ) {
clearTimeout( timeoutId );
timeoutId = setTimeout( () => fn.apply( this, args ), ms );
};
}
function isFunction( val ) {
return typeof val === 'function';
}
function intersection( a, b ) {
const s = new Set( b );
return a.filter( x => s.has( x ) );
}
function capitalize( [ first, ...rest ], lowerRest = false ) {
return first.toUpperCase() + ( lowerRest ? rest.join( '' ).toLowerCase() : rest.join( '' ) );
}
function isBoolean( val ) {
return typeof val === 'boolean';
}
function is( type, val ) {
return val instanceof type;
}
function intersectionWith( a, b, comp ) {
return a.filter( x => b.findIndex( y => comp( x, y ) ) !== -1 );
}
function intersectionBy( a, b, fn ) {
const s = new Set( b.map( x => fn( x ) ) );
return a.filter( x => s.has( fn( x ) ) );
}
function invertKeyValues( obj, fn ) {
return Object.keys( obj ).reduce( ( acc, key ) => {
const val = fn ? fn( obj[ key ] ) : obj[ key ];
acc[ val ] = acc[ val ] || [];
acc[ val ].push( key );
return acc;
}, {} );
}
function isAbsoluteURL( str ) {
return /^[a-z][a-z0-9+.-]*:/.test( str );
}
function isArrayLike( val ) {
try {
return [ ...val ], true;
} catch ( e ) {
return false;
}
}
window.addEventListener(
'resize',
debounce( () => {
console.log( window.innerWidth );
console.log( window.innerHeight );
}, 250 )
); // Will log the window dimensions at most every 250ms
const debouncePromise = ( fn, ms = 0 ) => {
let timeoutId;
const pending = [];
return ( ...args ) =>
new Promise( ( res, rej ) => {
clearTimeout( timeoutId );
timeoutId = setTimeout( () => {
const currentPending = [ ...pending ];
pending.length = 0;
Promise.resolve( fn.apply( this, args ) ).then(
data => {
currentPending.forEach( ( { resolve } ) => resolve( data ) );
},
error => {
currentPending.forEach( ( { reject } ) => reject( error ) );
}
);
}, ms );
pending.push( { resolve: res, reject: rej } );
} );
};
const fn = arg => new Promise( resolve => {
setTimeout( resolve, 1000, [ 'resolved', arg ] );
} );
const debounced = debouncePromise( fn, 200 );
debounced( 'foo' ).then( console.log );
debounced( 'bar' ).then( console.log );
// Will log ['resolved', 'bar'] both times
const decapitalize = ( [ first, ...rest ], upperRest = false ) =>
first.toLowerCase() +
( upperRest ? rest.join( '' ).toUpperCase() : rest.join( '' ) );
decapitalize( 'FooBar' ); // 'fooBar'
decapitalize( 'FooBar', true ); // 'fOOBAR'
const deepClone = obj => {
if ( obj === null ) return null;
let clone = Object.assign( {}, obj );
Object.keys( clone ).forEach(
key =>
( clone[ key ] =
typeof obj[ key ] === 'object' ? deepClone( obj[ key ] ) : obj[ key ] )
);
if ( Array.isArray( obj ) ) {
clone.length = obj.length;
return Array.from( clone );
}
return clone;
};
const a = { foo: 'bar', obj: { a: 1, b: 2 } };
const b = deepClone( a ); // a !== b, a.obj !== b.obj
const deepFlatten = arr =>
[].concat( ...arr.map( v => ( Array.isArray( v ) ? deepFlatten( v ) : v ) ) );
deepFlatten( [ 1, [ 2 ], [ [ 3 ], 4 ], 5 ] ); // [1, 2, 3, 4, 5]
const deepFreeze = obj => {
Object.keys( obj ).forEach( prop => {
if ( typeof obj[ prop ] === 'object' ) deepFreeze( obj[ prop ] );
} );
return Object.freeze( obj );
};
'use strict';
const val = deepFreeze( [ 1, [ 2, 3 ] ] );
val[ 0 ] = 3; // not allowed
val[ 1 ][ 0 ] = 4; // not allowed as well
const deepGet = ( obj, keys ) =>
keys.reduce(
( xs, x ) => ( xs && xs[ x ] !== null && xs[ x ] !== undefined ? xs[ x ] : null ),
obj
);
let index = 2;
const data = {
foo: {
foz: [ 1, 2, 3 ],
bar: {
baz: [ 'a', 'b', 'c' ]
}
}
};
deepGet( data, [ 'foo', 'foz', index ] ); // get 3
deepGet( data, [ 'foo', 'bar', 'baz', 8, 'foz' ] ); // null
const deepMapKeys = ( obj, fn ) =>
Array.isArray( obj )
? obj.map( val => deepMapKeys( val, fn ) )
: typeof obj === 'object'
? Object.keys( obj ).reduce( ( acc, current ) => {
const key = fn( current );
const val = obj[ current ];
acc[ key ] =
val !== null && typeof val === 'object' ? deepMapKeys( val, fn ) : val;
return acc;
}, {} )
: obj;
const obj = {
foo: '1',
nested: {
child: {
withArray: [
{
grandChild: [ 'hello' ]
}
]
}
}
};
const upperKeysObj = deepMapKeys( obj, key => key.toUpperCase() );
/*
{
"FOO":"1",
"NESTED":{
"CHILD":{
"WITHARRAY":[
{
"GRANDCHILD":[ 'hello' ]
}
]
}
}
}
*/
const deepMerge = ( a, b, fn ) =>
[ ...new Set( [ ...Object.keys( a ), ...Object.keys( b ) ] ) ].reduce(
( acc, key ) => ( { ...acc, [ key ]: fn( key, a[ key ], b[ key ] ) } ),
{}
);
deepMerge(
{ a: true, b: { c: [ 1, 2, 3 ] } },
{ a: false, b: { d: [ 1, 2, 3 ] } },
( key, a, b ) => ( key === 'a' ? a && b : Object.assign( {}, a, b ) )
);
// { a: false, b: { c: [ 1, 2, 3 ], d: [ 1, 2, 3 ] } }
const defaults = ( obj, ...defs ) =>
Object.assign( {}, obj, ...defs.reverse(), obj );
defaults( { a: 1 }, { b: 2 }, { b: 6 }, { a: 3 } ); // { a: 1, b: 2 }
const defer = ( fn, ...args ) => setTimeout( fn, 1, ...args );
// Example A:
defer( console.log, 'a' ), console.log( 'b' ); // logs 'b' then 'a'
// Example B:
document.querySelector( '#someElement' ).innerHTML = 'Hello';
longRunningFunction();
// Browser will not update the HTML until this has finished
defer( longRunningFunction );
// Browser will update the HTML then run the function
const degreesToRads = deg => ( deg * Math.PI ) / 180.0;
degreesToRads( 90.0 ); // ~1.5708
const delay = ( fn, ms, ...args ) => setTimeout( fn, ms, ...args );
delay(
function ( text ) {
console.log( text );
},
1000,
'later'
); // Logs 'later' after one second.
const detectDeviceType = () =>
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
)
? 'Mobile'
: 'Desktop';
detectDeviceType(); // 'Mobile' or 'Desktop'
const detectLanguage = ( defaultLang = 'en-US' ) =>
navigator.language ||
( Array.isArray( navigator.languages ) && navigator.languages[ 0 ] ) ||
defaultLang;
detectLanguage(); // 'nl-NL'
const difference = ( a, b ) => {
const s = new Set( b );
return a.filter( x => !s.has( x ) );
};
difference( [ 1, 2, 3, 3 ], [ 1, 2, 4 ] ); // [3, 3]
const differenceBy = ( a, b, fn ) => {
const s = new Set( b.map( fn ) );
return a.map( fn ).filter( el => !s.has( el ) );
};
differenceBy( [ 2.1, 1.2 ], [ 2.3, 3.4 ], Math.floor ); // [1]
differenceBy( [ { x: 2 }, { x: 1 } ], [ { x: 1 } ], v => v.x ); // [2]
const differenceWith = ( arr, val, comp = ( a, b ) => a === b ) =>
arr.filter( a => val.findIndex( b => comp( a, b ) ) === -1 );
differenceWith(
[ 1, 1.2, 1.5, 3, 0 ],
[ 1.9, 3, 0 ],
( a, b ) => Math.round( a ) === Math.round( b )
); // [1, 1.2]
differenceWith( [ 1, 1.2, 1.3 ], [ 1, 1.3, 1.5 ] ); // [1.2]
const dig = ( obj, target ) =>
target in obj
? obj[ target ]
: Object.values( obj ).reduce( ( acc, val ) => {
if ( acc !== undefined ) return acc;
if ( typeof val === 'object' ) return dig( val, target );
}, undefined );
const data = {
level1: {
level2: {
level3: 'some data'
}
}
};
dig( data, 'level3' ); // 'some data'
dig( data, 'level4' ); // undefined
const digitize = n => [ ...`${ Math.abs( n ) }` ].map( i => parseInt( i ) );
digitize( 123 ); // [1, 2, 3]
digitize( -123 ); // [1, 2, 3]
const distance = ( x0, y0, x1, y1 ) => Math.hypot( x1 - x0, y1 - y0 );
distance( 1, 1, 2, 3 ); // ~2.2361
const divmod = ( x, y ) => [ Math.floor( x / y ), x % y ];
divmod( 8, 3 ); // [2, 2]
divmod( 3, 8 ); // [0, 3]
divmod( 5, 5 ); // [1, 0]
const drop = ( arr, n = 1 ) => arr.slice( n );
drop( [ 1, 2, 3 ] ); // [2, 3]
drop( [ 1, 2, 3 ], 2 ); // [3]
drop( [ 1, 2, 3 ], 42 ); // []
const dropRight = ( arr, n = 1 ) => arr.slice( 0, -n );
dropRight( [ 1, 2, 3 ] ); // [1, 2]
dropRight( [ 1, 2, 3 ], 2 ); // [1]
dropRight( [ 1, 2, 3 ], 42 ); // []
const dropRightWhile = ( arr, func ) => {
let rightIndex = arr.length;
while ( rightIndex-- && !func( arr[ rightIndex ] ) );
return arr.slice( 0, rightIndex + 1 );
};
dropRightWhile( [ 1, 2, 3, 4 ], n => n < 3 ); // [1, 2]
const dropWhile = ( arr, func ) => {
while ( arr.length > 0 && !func( arr[ 0 ] ) ) arr = arr.slice( 1 );
return arr;
};
dropWhile( [ 1, 2, 3, 4 ], n => n >= 3 ); // [3, 4]
const either = ( f, g ) => ( ...args ) => f( ...args ) || g( ...args );
const isEven = num => num % 2 === 0;
const isPositive = num => num > 0;
const isPositiveOrEven = either( isPositive, isEven );
isPositiveOrEven( 4 ); // true
isPositiveOrEven( 3 ); // true
const elementContains = ( parent, child ) =>
parent !== child && parent.contains( child );
elementContains(
document.querySelector( 'head' ),
document.querySelector( 'title' )
);
// true
elementContains( document.querySelector( 'body' ), document.querySelector( 'body' ) );
// false
const elementIsFocused = el => ( el === document.activeElement );
elementIsFocused( el ); // true if the element is focused
function elementIsVisibleInViewport( el, partiallyVisible = false ) {
const { top, left, bottom, right } = el.getBoundingClientRect();
const { innerHeight, innerWidth } = window;
return partiallyVisible
? ( ( top > 0 && top < innerHeight ) ||
( bottom > 0 && bottom < innerHeight ) ) &&
( ( left > 0 && left < innerWidth ) || ( right > 0 && right < innerWidth ) )
: top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
}
function bottomVisible() {
return document.documentElement.clientHeight + window.scrollY >=
( document.documentElement.scrollHeight || document.documentElement.clientHeight );
}
// e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10}
elementIsVisibleInViewport( el ); // false - (not fully visible)
elementIsVisibleInViewport( el, true ); // true - (partially visible)
const equals = ( a, b ) => {
if ( a === b ) return true;
if ( a instanceof Date && b instanceof Date )
return a.getTime() === b.getTime();
if ( !a || !b || ( typeof a !== 'object' && typeof b !== 'object' ) )
return a === b;
if ( a.prototype !== b.prototype ) return false;
const keys = Object.keys( a );
if ( keys.length !== Object.keys( b ).length ) return false;
return keys.every( k => equals( a[ k ], b[ k ] ) );
};
equals(
{ a: [ 2, { e: 3 } ], b: [ 4 ], c: 'foo' },
{ a: [ 2, { e: 3 } ], b: [ 4 ], c: 'foo' }
); // true
equals( [ 1, 2, 3 ], { 0: 1, 1: 2, 2: 3 } ); // true
const escapeHTML = str =>
str.replace(
/[&<>'"]/g,
tag =>
( {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
"'": '&#39;',
'"': '&quot;'
}[ tag ] || tag )
);
escapeHTML( '<a href="#">Me & you</a>' );
// '&lt;a href=&quot;#&quot;&gt;Me &amp; you&lt;/a&gt;'
const escapeRegExp = str => str.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' );
escapeRegExp( '(test)' ); // \\(test\\)
const euclideanDistance = ( a, b ) =>
Math.hypot( ...Object.keys( a ).map( k => b[ k ] - a[ k ] ) );
euclideanDistance( [ 1, 1 ], [ 2, 3 ] ); // ~2.2361
euclideanDistance( [ 1, 1, 1 ], [ 2, 3, 2 ] ); // ~2.4495
const everyNth = ( arr, nth ) => arr.filter( ( e, i ) => i % nth === nth - 1 );
everyNth( [ 1, 2, 3, 4, 5, 6 ], 2 ); // [ 2, 4, 6 ]
const expandTabs = ( str, count ) => str.replace( /\t/g, ' '.repeat( count ) );
expandTabs( '\t\tlorem', 3 ); // ' lorem'
const extendHex = shortHex =>
'#' +
shortHex
.slice( shortHex.startsWith( '#' ) ? 1 : 0 )
.split( '' )
.map( x => x + x )
.join( '' );
extendHex( '#03f' ); // '#0033ff'
extendHex( '05a' ); // '#0055aa'
const factorial = n =>
n < 0
? ( () => {
throw new TypeError( 'Negative numbers are not allowed!' );
} )()
: n <= 1
? 1
: n * factorial( n - 1 );
factorial( 6 ); // 720
const fahrenheitToCelsius = degrees => ( degrees - 32 ) * 5 / 9;
fahrenheitToCelsius( 32 ); // 0
const fibonacci = n =>
Array.from( { length: n } ).reduce(
( acc, val, i ) => acc.concat( i > 1 ? acc[ i - 1 ] + acc[ i - 2 ] : i ),
[]
);
fibonacci( 6 ); // [0, 1, 1, 2, 3, 5]
const filterNonUnique = arr =>
[ ...new Set( arr ) ].filter( i => arr.indexOf( i ) === arr.lastIndexOf( i ) );
filterNonUnique( [ 1, 2, 2, 3, 4, 4, 5 ] ); // [1, 3, 5]
const filterNonUniqueBy = ( arr, fn ) =>
arr.filter( ( v, i ) => arr.every( ( x, j ) => ( i === j ) === fn( v, x, i, j ) ) );
filterNonUniqueBy(
[
{ id: 0, value: 'a' },
{ id: 1, value: 'b' },
{ id: 2, value: 'c' },
{ id: 1, value: 'd' },
{ id: 0, value: 'e' }
],
( a, b ) => a.id === b.id
); // [ { id: 2, value: 'c' } ]
const filterUnique = arr =>
[ ...new Set( arr ) ].filter( i => arr.indexOf( i ) !== arr.lastIndexOf( i ) );
filterUnique( [ 1, 2, 2, 3, 4, 4, 5 ] ); // [2, 4]
const filterUniqueBy = ( arr, fn ) =>
arr.filter( ( v, i ) => arr.some( ( x, j ) => ( i !== j ) === fn( v, x, i, j ) ) );
filterUniqueBy(
[
{ id: 0, value: 'a' },
{ id: 1, value: 'b' },
{ id: 2, value: 'c' },
{ id: 3, value: 'd' },
{ id: 0, value: 'e' }
],
( a, b ) => a.id == b.id
); // [ { id: 0, value: 'a' }, { id: 0, value: 'e' } ]
const findClosestAnchor = node => {
for ( let n = node; n.parentNode; n = n.parentNode )
if ( n.nodeName.toLowerCase() === 'a' ) return n;
return null;
};
findClosestAnchor( document.querySelector( 'a > span' ) ); // a
const findClosestMatchingNode = ( node, selector ) => {
for ( let n = node; n.parentNode; n = n.parentNode )
if ( n.matches && n.matches( selector ) ) return n;
return null;
};
findClosestMatchingNode( document.querySelector( 'span' ), 'body' ); // body
const findFirstN = ( arr, matcher, n = 1 ) => {
let res = [];
for ( let i in arr ) {
const el = arr[ i ];
const match = matcher( el, i, arr );
if ( match ) res.push( el );
if ( res.length === n ) return res;
}
return res;
};
findFirstN( [ 1, 2, 4, 6 ], n => n % 2 === 0, 2 ); // [2, 4]
findFirstN( [ 1, 2, 4, 6 ], n => n % 2 === 0, 5 ); // [2, 4, 6]
const findKey = ( obj, fn ) =>
Object.keys( obj ).find( key => fn( obj[ key ], key, obj ) );
findKey(
{
barney: { age: 36, active: true },
fred: { age: 40, active: false },
pebbles: { age: 1, active: true }
},
x => x[ 'active' ]
); // 'barney'
const findKeys = ( obj, val ) =>
Object.keys( obj ).filter( key => obj[ key ] === val );
const ages = {
Leo: 20,
Zoey: 21,
Jane: 20,
};
findKeys( ages, 20 ); // [ 'Leo', 'Jane' ]
const findLast = ( arr, fn ) => arr.filter( fn ).pop();
findLast( [ 1, 2, 3, 4 ], n => n % 2 === 1 ); // 3
const findLastIndex = ( arr, fn ) =>
( arr
.map( ( val, i ) => [ i, val ] )
.filter( ( [ i, val ] ) => fn( val, i, arr ) )
.pop() || [ -1 ] )[ 0 ];
findLastIndex( [ 1, 2, 3, 4 ], n => n % 2 === 1 ); // 2 (index of the value 3)
findLastIndex( [ 1, 2, 3, 4 ], n => n === 5 ); // -1 (default value when not found)
const findLastKey = ( obj, fn ) =>
Object.keys( obj )
.reverse()
.find( key => fn( obj[ key ], key, obj ) );
findLastKey(
{
barney: { age: 36, active: true },
fred: { age: 40, active: false },
pebbles: { age: 1, active: true }
},
x => x[ 'active' ]
); // 'pebbles'
const findLastN = ( arr, matcher, n = 1 ) => {
let res = [];
for ( let i = arr.length - 1; i >= 0; i-- ) {
const el = arr[ i ];
const match = matcher( el, i, arr );
if ( match ) res.unshift( el );
if ( res.length === n ) return res;
}
return res;
};
findLastN( [ 1, 2, 4, 6 ], n => n % 2 === 0, 2 ); // [4, 6]
findLastN( [ 1, 2, 4, 6 ], n => n % 2 === 0, 5 ); // [2, 4, 6]
const flatten = ( arr, depth = 1 ) =>
arr.reduce(
( a, v ) =>
a.concat( depth > 1 && Array.isArray( v ) ? flatten( v, depth - 1 ) : v ),
[]
);
flatten( [ 1, [ 2 ], 3, 4 ] ); // [1, 2, 3, 4]
flatten( [ 1, [ 2, [ 3, [ 4, 5 ], 6 ], 7 ], 8 ], 2 ); // [1, 2, 3, [4, 5], 6, 7, 8]
const flattenObject = ( obj, prefix = '' ) =>
Object.keys( obj ).reduce( ( acc, k ) => {
const pre = prefix.length ? `${ prefix }.` : '';
if (
typeof obj[ k ] === 'object' &&
obj[ k ] !== null &&
Object.keys( obj[ k ] ).length > 0
)
Object.assign( acc, flattenObject( obj[ k ], pre + k ) );
else acc[ pre + k ] = obj[ k ];
return acc;
}, {} );
flattenObject( { a: { b: { c: 1 } }, d: 1 } ); // { 'a.b.c': 1, d: 1 }
const flip = fn => ( first, ...rest ) => fn( ...rest, first );
let a = { name: 'John Smith' };
let b = {};
const mergeFrom = flip( Object.assign );
let mergePerson = mergeFrom.bind( null, a );
mergePerson( b ); // == b
b = {};
Object.assign( b, a ); // == b
const forEachRight = ( arr, callback ) =>
arr
.slice()
.reverse()
.forEach( callback );
forEachRight( [ 1, 2, 3, 4 ], val => console.log( val ) ); // '4', '3', '2', '1'
const forOwn = ( obj, fn ) =>
Object.keys( obj ).forEach( key => fn( obj[ key ], key, obj ) );
forOwn( { foo: 'bar', a: 1 }, v => console.log( v ) ); // 'bar', 1
const forOwnRight = ( obj, fn ) =>
Object.keys( obj )
.reverse()
.forEach( key => fn( obj[ key ], key, obj ) );
forOwnRight( { foo: 'bar', a: 1 }, v => console.log( v ) ); // 1, 'bar'
const formToObject = form =>
Array.from( new FormData( form ) ).reduce(
( acc, [ key, value ] ) => ( {
...acc,
[ key ]: value
} ),
{}
);
formToObject( document.querySelector( '#form' ) );
// { email: '[email protected]', name: 'Test Name' }
const formatDuration = ms => {
if ( ms < 0 ) ms = -ms;
const time = {
day: Math.floor( ms / 86400000 ),
hour: Math.floor( ms / 3600000 ) % 24,
minute: Math.floor( ms / 60000 ) % 60,
second: Math.floor( ms / 1000 ) % 60,
millisecond: Math.floor( ms ) % 1000
};
return Object.entries( time )
.filter( val => val[ 1 ] !== 0 )
.map( ( [ key, val ] ) => `${ val } ${ key }${ val !== 1 ? 's' : '' }` )
.join( ', ' );
};
formatDuration( 1001 ); // '1 second, 1 millisecond'
formatDuration( 34325055574 );
// '397 days, 6 hours, 44 minutes, 15 seconds, 574 milliseconds'
const formatNumber = num => num.toLocaleString();
formatNumber( 123456 ); // '123,456' in `en-US`
formatNumber( 15675436903 ); // '15.675.436.903' in `de-DE`
const formatSeconds = s => {
const [ hour, minute, second, sign ] =
s > 0
? [ s / 3600, ( s / 60 ) % 60, s % 60, '' ]
: [ -s / 3600, ( -s / 60 ) % 60, -s % 60, '-' ];
return (
sign +
[ hour, minute, second ]
.map( v => `${ Math.floor( v ) }`.padStart( 2, '0' ) )
.join( ':' )
);
};
formatSeconds( 200 ); // '00:03:20'
formatSeconds( -200 ); // '-00:03:20'
formatSeconds( 99999 ); // '27:46:39'
const frequencies = arr =>
arr.reduce( ( a, v ) => {
a[ v ] = a[ v ] ? a[ v ] + 1 : 1;
return a;
}, {} );
frequencies( [ 'a', 'b', 'a', 'c', 'a', 'a', 'b' ] ); // { a: 4, b: 2, c: 1 }
frequencies( [ ...'ball' ] ); // { b: 1, a: 1, l: 2 }
const fromCamelCase = ( str, separator = '_' ) =>
str
.replace( /([a-z\d])([A-Z])/g, '$1' + separator + '$2' )
.replace( /([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2' )
.toLowerCase();
fromCamelCase( 'someDatabaseFieldName', ' ' ); // 'some database field name'
fromCamelCase( 'someLabelThatNeedsToBeDecamelized', '-' );
// 'some-label-that-needs-to-be-decamelized'
fromCamelCase( 'someJavascriptProperty', '_' ); // 'some_javascript_property'
fromCamelCase( 'JSONToCSV', '.' ); // 'json.to.csv'
const fromTimestamp = timestamp => new Date( timestamp * 1000 );
fromTimestamp( 1602162242 ); // 2020-10-08T13:04:02.000Z
const frozenSet = iterable => {
const s = new Set( iterable );
s.add = undefined;
s.delete = undefined;
s.clear = undefined;
return s;
};
frozenSet( [ 1, 2, 3, 1, 2 ] );
// Set { 1, 2, 3, add: undefined, delete: undefined, clear: undefined }
const fullscreen = ( mode = true, el = 'body' ) =>
mode
? document.querySelector( el ).requestFullscreen()
: document.exitFullscreen();
fullscreen(); // Opens `body` in fullscreen mode
fullscreen( false ); // Exits fullscreen mode
const functionName = fn => ( console.debug( fn.name ), fn );
let m = functionName( Math.max )( 5, 6 );
// max (logged in debug channel of console)
// m = 6
const functions = ( obj, inherited = false ) =>
( inherited
? [ ...Object.keys( obj ), ...Object.keys( Object.getPrototypeOf( obj ) ) ]
: Object.keys( obj )
).filter( key => typeof obj[ key ] === 'function' );
function Foo() {
this.a = () => 1;
this.b = () => 2;
}
Foo.prototype.c = () => 3;
functions( new Foo() ); // ['a', 'b']
functions( new Foo(), true ); // ['a', 'b', 'c']
const gcd = ( ...arr ) => {
const _gcd = ( x, y ) => ( !y ? x : gcd( y, x % y ) );
return [ ...arr ].reduce( ( a, b ) => _gcd( a, b ) );
};
gcd( 8, 36 ); // 4
gcd( ...[ 12, 8, 32 ] ); // 4
const generateItems = ( n, fn ) => Array.from( { length: n }, ( _, i ) => fn( i ) );
generateItems( 10, Math.random );
// [0.21, 0.08, 0.40, 0.96, 0.96, 0.24, 0.19, 0.96, 0.42, 0.70]
const generatorToArray = gen => [ ...gen ];
const s = new Set( [ 1, 2, 1, 3, 1, 4 ] );
generatorToArray( s.entries() ); // [[ 1, 1 ], [ 2, 2 ], [ 3, 3 ], [ 4, 4 ]]
const geometricProgression = ( end, start = 1, step = 2 ) =>
Array.from( {
length: Math.floor( Math.log( end / start ) / Math.log( step ) ) + 1,
} ).map( ( _, i ) => start * step ** i );
geometricProgression( 256 ); // [1, 2, 4, 8, 16, 32, 64, 128, 256]
geometricProgression( 256, 3 ); // [3, 6, 12, 24, 48, 96, 192]
geometricProgression( 256, 1, 4 ); // [1, 4, 16, 64, 256]
const get = ( from, ...selectors ) =>
[ ...selectors ].map( s =>
s
.replace( /\[([^\[\]]*)\]/g, '.$1.' )
.split( '.' )
.filter( t => t !== '' )
.reduce( ( prev, cur ) => prev && prev[ cur ], from )
);
const obj = {
selector: { to: { val: 'val to select' } },
target: [ 1, 2, { a: 'test' } ],
};
get( obj, 'selector.to.val', 'target[0]', 'target[2].a' );
// ['val to select', 1, 'test']
const getAncestors = el => {
let ancestors = [];
while ( el ) {
ancestors.unshift( el );
el = el.parentNode;
}
return ancestors;
};
getAncestors( document.querySelector( 'nav' ) );
// [document, html, body, header, nav]
const getBaseURL = url => url.replace( /[?#].*$/, '' );
getBaseURL( 'http://url.com/page?name=Adam&surname=Smith' );
// 'http://url.com/page'
const getColonTimeFromDate = date => date.toTimeString().slice( 0, 8 );
getColonTimeFromDate( new Date() ); // '08:38:00'
const getDaysDiffBetweenDates = ( dateInitial, dateFinal ) =>
( dateFinal - dateInitial ) / ( 1000 * 3600 * 24 );
getDaysDiffBetweenDates( new Date( '2017-12-13' ), new Date( '2017-12-22' ) ); // 9
const getElementsBiggerThanViewport = () => {
const docWidth = document.documentElement.offsetWidth;
return [ ...document.querySelectorAll( '*' ) ].filter(
el => el.offsetWidth > docWidth
);
};
getElementsBiggerThanViewport(); // <div id="ultra-wide-item" />
const getHoursDiffBetweenDates = ( dateInitial, dateFinal ) =>
( dateFinal - dateInitial ) / ( 1000 * 3600 );
getHoursDiffBetweenDates(
new Date( '2021-04-24 10:25:00' ),
new Date( '2021-04-25 10:25:00' )
); // 24
const getImages = ( el, includeDuplicates = false ) => {
const images = [ ...el.getElementsByTagName( 'img' ) ].map( img =>
img.getAttribute( 'src' )
);
return includeDuplicates ? images : [ ...new Set( images ) ];
};
getImages( document, true ); // ['image1.jpg', 'image2.png', 'image1.png', '...']
getImages( document, false ); // ['image1.jpg', 'image2.png', '...']
const getMeridiemSuffixOfInteger = num =>
num === 0 || num === 24
? 12 + 'am'
: num === 12
? 12 + 'pm'
: num < 12
? ( num % 12 ) + 'am'
: ( num % 12 ) + 'pm';
getMeridiemSuffixOfInteger( 0 ); // '12am'
getMeridiemSuffixOfInteger( 11 ); // '11am'
getMeridiemSuffixOfInteger( 13 ); // '1pm'
getMeridiemSuffixOfInteger( 25 ); // '1pm'
const getMinutesDiffBetweenDates = ( dateInitial, dateFinal ) =>
( dateFinal - dateInitial ) / ( 1000 * 60 );
getMinutesDiffBetweenDates(
new Date( '2021-04-24 01:00:15' ),
new Date( '2021-04-24 02:00:15' )
); // 60
const getMonthsDiffBetweenDates = ( dateInitial, dateFinal ) =>
Math.max(
( dateFinal.getFullYear() - dateInitial.getFullYear() ) * 12 +
dateFinal.getMonth() -
dateInitial.getMonth(),
0
);
getMonthsDiffBetweenDates( new Date( '2017-12-13' ), new Date( '2018-04-29' ) ); // 4
const getParentsUntil = ( el, selector ) => {
let parents = [],
_el = el.parentNode;
while ( _el && typeof _el.matches === 'function' ) {
parents.unshift( _el );
if ( _el.matches( selector ) ) return parents;
else _el = _el.parentNode;
}
return [];
};
getParentsUntil( document.querySelector( '#home-link' ), 'header' );
// [header, nav, ul, li]
const getProtocol = () => window.location.protocol;
getProtocol(); // 'https:'
const getScrollPosition = ( el = window ) => ( {
x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
} );
getScrollPosition(); // {x: 0, y: 200}
const getSecondsDiffBetweenDates = ( dateInitial, dateFinal ) =>
( dateFinal - dateInitial ) / 1000;
getSecondsDiffBetweenDates(
new Date( '2020-12-24 00:00:15' ),
new Date( '2020-12-24 00:00:17' )
); // 2
const getSelectedText = () => window.getSelection().toString();
getSelectedText(); // 'Lorem ipsum'
const getSiblings = el =>
[ ...el.parentNode.childNodes ].filter( node => node !== el );
getSiblings( document.querySelector( 'head' ) ); // ['body']
const getStyle = ( el, ruleName ) => getComputedStyle( el )[ ruleName ];
getStyle( document.querySelector( 'p' ), 'font-size' ); // '16px'
const getTimestamp = ( date = new Date() ) => Math.floor( date.getTime() / 1000 );
getTimestamp(); // 1602162242
const getType = v =>
( v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name );
getType( new Set( [ 1, 2, 3 ] ) ); // 'Set'
const getURLParameters = url =>
( url.match( /([^?=&]+)(=([^&]*))/g ) || [] ).reduce(
( a, v ) => (
( a[ v.slice( 0, v.indexOf( '=' ) ) ] = v.slice( v.indexOf( '=' ) + 1 ) ), a
),
{}
);
getURLParameters( 'google.com' ); // {}
getURLParameters( 'http://url.com/page?name=Adam&surname=Smith' );
// {name: 'Adam', surname: 'Smith'}
function getVerticalOffset( el ) {
let offset = el.offsetTop, _el = el;
while ( _el.offsetParent ) {
_el = _el.offsetParent;
offset += _el.offsetTop;
}
return offset;
}
getVerticalOffset( '.my-element' ); // 120
const groupBy = ( arr, fn ) =>
arr
.map( typeof fn === 'function' ? fn : val => val[ fn ] )
.reduce( ( acc, val, i ) => {
acc[ val ] = ( acc[ val ] || [] ).concat( arr[ i ] );
return acc;
}, {} );
groupBy( [ 6.1, 4.2, 6.3 ], Math.floor ); // {4: [4.2], 6: [6.1, 6.3]}
groupBy( [ 'one', 'two', 'three' ], 'length' ); // {3: ['one', 'two'], 5: ['three']}
const hammingDistance = ( num1, num2 ) =>
( ( num1 ^ num2 ).toString( 2 ).match( /1/g ) || '' ).length;
hammingDistance( 2, 3 ); // 1
const hasClass = ( el, className ) => el.classList.contains( className );
hasClass( document.querySelector( 'p.special' ), 'special' ); // true
function hasDuplicates( arr ) {
return new Set( arr ).size !== arr.length;
}
hasDuplicates( [ 0, 1, 1, 2 ] ); // true
hasDuplicates( [ 0, 1, 2, 3 ] ); // false
const hasFlags = ( ...flags ) =>
flags.every( flag =>
process.argv.includes( /^-{1,2}/.test( flag ) ? flag : '--' + flag )
);
// node myScript.js -s --test --cool=true
hasFlags( '-s' ); // true
hasFlags( '--test', 'cool=true', '-s' ); // true
hasFlags( 'special' ); // false
const hasKey = ( obj, keys ) => {
return (
keys.length > 0 &&
keys.every( key => {
if ( typeof obj !== 'object' || !obj.hasOwnProperty( key ) ) return false;
obj = obj[ key ];
return true;
} )
);
};
let obj = {
a: 1,
b: { c: 4 },
'b.d': 5
};
hasKey( obj, [ 'a' ] ); // true
hasKey( obj, [ 'b' ] ); // true
hasKey( obj, [ 'b', 'c' ] ); // true
hasKey( obj, [ 'b.d' ] ); // true
hasKey( obj, [ 'd' ] ); // false
hasKey( obj, [ 'c' ] ); // false
hasKey( obj, [ 'b', 'f' ] ); // false
const hasMany = ( arr, fn ) => arr.filter( fn ).length > 1;
hasMany( [ 1, 3 ], x => x % 2 ); // true
hasMany( [ 1, 2 ], x => x % 2 ); // false
const hasOne = ( arr, fn ) => arr.filter( fn ).length === 1;
hasOne( [ 1, 2 ], x => x % 2 ); // true
hasOne( [ 1, 3 ], x => x % 2 ); // false
const hashBrowser = val =>
crypto.subtle
.digest( 'SHA-256', new TextEncoder( 'utf-8' ).encode( val ) )
.then( h => {
let hexes = [],
view = new DataView( h );
for ( let i = 0; i < view.byteLength; i += 4 )
hexes.push( ( '00000000' + view.getUint32( i ).toString( 16 ) ).slice( -8 ) );
return hexes.join( '' );
} );
hashBrowser(
JSON.stringify( { a: 'a', b: [ 1, 2, 3, 4 ], foo: { c: 'bar' } } )
).then( console.log );
// '04aa106279f5977f59f9067fa9712afc4aedc6f5862a8defc34552d8c7206393'
const crypto = require( 'crypto' );
const { createEventHub } = require( "./createEventHub" );
const hashNode = val =>
new Promise( resolve =>
setTimeout(
() => resolve( crypto.createHash( 'sha256' ).update( val ).digest( 'hex' ) ),
0
)
);
hashNode( JSON.stringify( { a: 'a', b: [ 1, 2, 3, 4 ], foo: { c: 'bar' } } ) ).then(
console.log
);
// '04aa106279f5977f59f9067fa9712afc4aedc6f5862a8defc34552d8c7206393'
const haveSameContents = ( a, b ) => {
for ( const v of new Set( [ ...a, ...b ] ) )
if ( a.filter( e => e === v ).length !== b.filter( e => e === v ).length )
return false;
return true;
};
haveSameContents( [ 1, 2, 4 ], [ 2, 4, 1 ] ); // true
const head = arr => ( arr && arr.length ? arr[ 0 ] : undefined );
head( [ 1, 2, 3 ] ); // 1
head( [] ); // undefined
head( null ); // undefined
head( undefined ); // undefined
const heapsort = arr => {
const a = [ ...arr ];
let l = a.length;
const heapify = ( a, i ) => {
const left = 2 * i + 1;
const right = 2 * i + 2;
let max = i;
if ( left < l && a[ left ] > a[ max ] ) max = left;
if ( right < l && a[ right ] > a[ max ] ) max = right;
if ( max !== i ) {
[ a[ max ], a[ i ] ] = [ a[ i ], a[ max ] ];
heapify( a, max );
}
};
for ( let i = Math.floor( l / 2 ); i >= 0; i -= 1 ) heapify( a, i );
for ( i = a.length - 1; i > 0; i-- ) {
[ a[ 0 ], a[ i ] ] = [ a[ i ], a[ 0 ] ];
l--;
heapify( a, 0 );
}
return a;
};
heapsort( [ 6, 3, 4, 1 ] ); // [1, 3, 4, 6]
const hexToRGB = hex => {
let alpha = false,
h = hex.slice( hex.startsWith( '#' ) ? 1 : 0 );
if ( h.length === 3 ) h = [ ...h ].map( x => x + x ).join( '' );
else if ( h.length === 8 ) alpha = true;
h = parseInt( h, 16 );
return (
'rgb' +
( alpha ? 'a' : '' ) +
'(' +
( h >>> ( alpha ? 24 : 16 ) ) +
', ' +
( ( h & ( alpha ? 0x00ff0000 : 0x00ff00 ) ) >>> ( alpha ? 16 : 8 ) ) +
', ' +
( ( h & ( alpha ? 0x0000ff00 : 0x0000ff ) ) >>> ( alpha ? 8 : 0 ) ) +
( alpha ? `, ${ h & 0x000000ff }` : '' ) +
')'
);
};
hexToRGB( '#27ae60ff' ); // 'rgba(39, 174, 96, 255)'
hexToRGB( '27ae60' ); // 'rgb(39, 174, 96)'
hexToRGB( '#fff' ); // 'rgb(255, 255, 255)'
const hide = ( ...el ) => [ ...el ].forEach( e => ( e.style.display = 'none' ) );
hide( ...document.querySelectorAll( 'img' ) ); // Hides all <img> elements on the page
const httpDelete = ( url, callback, err = console.error ) => {
const request = new XMLHttpRequest();
request.open( 'DELETE', url, true );
request.onload = () => callback( request );
request.onerror = () => err( request );
request.send();
};
httpDelete( 'https://jsonplaceholder.typicode.com/posts/1', request => {
console.log( request.responseText );
} ); // Logs: {}
const httpGet = ( url, callback, err = console.error ) => {
const request = new XMLHttpRequest();
request.open( 'GET', url, true );
request.onload = () => callback( request.responseText );
request.onerror = () => err( request );
request.send();
};
httpGet(
'https://jsonplaceholder.typicode.com/posts/1',
console.log
); /*
Logs: {
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
*/
const httpPost = ( url, data, callback, err = console.error ) => {
const request = new XMLHttpRequest();
request.open( 'POST', url, true );
request.setRequestHeader( 'Content-type', 'application/json; charset=utf-8' );
request.onload = () => callback( request.responseText );
request.onerror = () => err( request );
request.send( data );
};
const newPost = {
userId: 1,
id: 1337,
title: 'Foo',
body: 'bar bar bar'
};
const data = JSON.stringify( newPost );
httpPost(
'https://jsonplaceholder.typicode.com/posts',
data,
console.log
); /*
Logs: {
"userId": 1,
"id": 1337,
"title": "Foo",
"body": "bar bar bar"
}
*/
httpPost(
'https://jsonplaceholder.typicode.com/posts',
null, // does not send a body
console.log
); /*
Logs: {
"id": 101
}
*/
const httpPut = ( url, data, callback, err = console.error ) => {
const request = new XMLHttpRequest();
request.open( 'PUT', url, true );
request.setRequestHeader( 'Content-type', 'application/json; charset=utf-8' );
request.onload = () => callback( request );
request.onerror = () => err( request );
request.send( data );
};
const password = 'fooBaz';
const data = JSON.stringify( {
id: 1,
title: 'foo',
body: 'bar',
userId: 1
} );
httpPut( 'https://jsonplaceholder.typicode.com/posts/1', data, request => {
console.log( request.responseText );
} ); /*
Logs: {
id: 1,
title: 'foo',
body: 'bar',
userId: 1
}
*/
const httpsRedirect = () => {
if ( location.protocol !== 'https:' )
location.replace( 'https://' + location.href.split( '//' )[ 1 ] );
};
httpsRedirect();
// If you are on http://mydomain.com, you are redirected to https://mydomain.com
const hz = ( fn, iterations = 100 ) => {
const before = performance.now();
for ( let i = 0; i < iterations; i++ ) fn();
return ( 1000 * iterations ) / ( performance.now() - before );
};
const numbers = Array( 10000 ).fill().map( ( _, i ) => i );
const sumReduce = () => numbers.reduce( ( acc, n ) => acc + n, 0 );
const sumForLoop = () => {
let sum = 0;
for ( let i = 0; i < numbers.length; i++ ) sum += numbers[ i ];
return sum;
};
Math.round( hz( sumReduce ) ); // 572
Math.round( hz( sumForLoop ) ); // 4784
const inRange = ( n, start, end = null ) => {
if ( end && start > end ) [ end, start ] = [ start, end ];
return end == null ? n >= 0 && n < start : n >= start && n < end;
};
inRange( 3, 2, 5 ); // true
inRange( 3, 4 ); // true
inRange( 2, 3, 5 ); // false
inRange( 3, 2 ); // false
const includesAll = ( arr, values ) => values.every( v => arr.includes( v ) );
includesAll( [ 1, 2, 3, 4 ], [ 1, 4 ] ); // true
includesAll( [ 1, 2, 3, 4 ], [ 1, 5 ] ); // false
const includesAny = ( arr, values ) => values.some( v => arr.includes( v ) );
includesAny( [ 1, 2, 3, 4 ], [ 2, 9 ] ); // true
includesAny( [ 1, 2, 3, 4 ], [ 8, 9 ] ); // false
const indentString = ( str, count, indent = ' ' ) =>
str.replace( /^/gm, indent.repeat( count ) );
indentString( 'Lorem\nIpsum', 2 ); // ' Lorem\n Ipsum'
indentString( 'Lorem\nIpsum', 2, '_' ); // '__Lorem\n__Ipsum'
const indexBy = ( arr, fn ) =>
arr.reduce( ( obj, v, i ) => {
obj[ fn( v, i, arr ) ] = v;
return obj;
}, {} );
indexBy( [
{ id: 10, name: 'apple' },
{ id: 20, name: 'orange' }
], x => x.id );
// { '10': { id: 10, name: 'apple' }, '20': { id: 20, name: 'orange' } }
const utilObj = {
"anagrams": function anagrams( str ) {
if ( str.length <= 2 )
return str.length === 2 ? [ str, str[ 1 ] + str[ 0 ] ] : [ str ];
return str
.split( '' )
.reduce(
( acc, letter, i ) => acc.concat( anagrams( str.slice( 0, i ) + str.slice( i + 1 ) ).map( val => letter + val ) ),
[]
);
},
"arrayToHtmlList": function arrayToHTMLList( arr, listID ) {
return document.querySelector( `#${ listID }` ).innerHTML += arr
.map( item => `<li>${ item }</li>` )
.join( '' );
},
"ary": function ary( fn, n ) {
return ( ...args ) => fn( ...args.slice( 0, n ) );
},
"atob": function atob( str ) {
return Buffer.from( str, 'base64' ).toString( 'binary' );
},
"average": function average( ...nums ) {
return nums.reduce( ( acc, val ) => acc + val, 0 ) / nums.length;
},
"aveargeBy": function averageBy( arr, fn ) {
return arr
.map( typeof fn === 'function' ? fn : val => val[ fn ] )
.reduce( ( acc, val ) => acc + val, 0 ) / arr.length;
},
"bind": function bind( fn, context, ...args ) {
return function () {
return fn.apply( context, args.concat( ...arguments ) );
};
},
"bindAll": function bindAll( obj, ...fns ) {
return fns.forEach(
fn => (
( f = obj[ fn ] ),
( obj[ fn ] = function () {
return f.apply( obj );
} )
)
);
},
"bindKey": function bindKey( context, fn, ...boundArgs ) {
return ( ...args ) => context[ fn ].apply( context, [ ...boundArgs, ...args ] );
},
"bota": function btoa( str ) {
return new Buffer( str, 'binary' ).toString( 'base64' );
},
"bottomVisible": function bottomVisible() {
return document.documentElement.clientHeight + window.scrollY >=
( document.documentElement.scrollHeight || document.documentElement.clientHeight );
},
"byteSize": function byteSize( str ) {
return new Blob( [ str ] ).size;
},
"call": function call( key, ...args ) {
return context => context[ key ]( ...args );
},
"capitalize": function capitalize( [ first, ...rest ], lowerRest = false ) {
return first.toUpperCase() + ( lowerRest ? rest.join( '' ).toLowerCase() : rest.join( '' ) );
},
"capitalizeEveryWord": function capitalizeEveryWord( str ) {
return str.replace( /\b[a-z]/g, char => char.toUpperCase() );
},
"castArray": function castArray( val ) {
return ( Array.isArray( val ) ? val : [ val ] );
},
"chainAsync":
function chainAsync( fns ) {
let curr = 0;
const next = () => fns[ curr++ ]( next );
next();
},
"chunk": function chunk( arr, size ) {
return Array.from( { length: Math.ceil( arr.length / size ) }, ( v, i ) => arr.slice( i * size, i * size + size )
);
},
"clampNumber": function clampNumber( num, a, b ) {
return Math.max( Math.min( num, Math.max( a, b ) ), Math.min( a, b ) );
},
"cloneRegExp":
function cloneRegExp( regExp ) {
return new RegExp( regExp.source, regExp.flags );
},
"coalesce": function coalesce( ...args ) {
return args.find( _ => ![ undefined, null ].includes( _ ) );
},
"coalesceFactory": function coalesceFactory( valid ) {
return ( ...args ) => args.find( valid );
},
"collectInto": function collectInto( fn ) {
return ( ...args ) => fn( args );
},
"colorize": function colorize( ...args ) {
return ( {
black: `\\x1b[30m${ args.join( ' ' ) }`,
red: `\\x1b[31m${ args.join( ' ' ) }`,
green: `\\x1b[32m${ args.join( ' ' ) }`,
yellow: `\\x1b[33m${ args.join( ' ' ) }`,
blue: `\\x1b[34m${ args.join( ' ' ) }`,
magenta: `\\x1b[35m${ args.join( ' ' ) }`,
cyan: `\\x1b[36m${ args.join( ' ' ) }`,
white: `\\x1b[37m${ args.join( ' ' ) }`,
bgBlack: `\\x1b[40m${ args.join( ' ' ) }\\x1b[0m`,
bgRed: `\\x1b[41m${ args.join( ' ' ) }\\x1b[0m`,
bgGreen: `\\x1b[42m${ args.join( ' ' ) }\\x1b[0m`,
bgYellow: `\\x1b[43m${ args.join( ' ' ) }\\x1b[0m`,
bgBlue: `\\x1b[44m${ args.join( ' ' ) }\\x1b[0m`,
bgMagenta: `\\x1b[45m${ args.join( ' ' ) }\\x1b[0m`,
bgCyan: `\\x1b[46m${ args.join( ' ' ) }\\x1b[0m`,
bgWhite: `\\x1b[47m${ args.join( ' ' ) }\\x1b[0m`
} );
},
"compact": function compact( arr ) {
return arr.filter( Boolean );
},
"compose": function compose( ...fns ) {
return fns.reduce( ( f, g ) => ( ...args ) => f( g( ...args ) ) );
},
"composeRight": function composeRight( ...fns ) {
return fns.reduce( ( f, g ) => ( ...args ) => g( f( ...args ) ) );
},
"copyToClipboard": function copyToClipboard( str ) {
const el = document.createElement( 'textarea' );
el.value = str;
el.setAttribute( 'readonly', '' );
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild( el );
const selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt( 0 ) : false;
el.select();
document.execCommand( 'copy' );
document.body.removeChild( el );
if ( selected ) {
document.getSelection().removeAllRanges();
document.getSelection().addRange( selected );
}
},
"countBy": function countBy( arr, fn ) {
return arr.map( typeof fn === 'function' ? fn : val => val[ fn ] ).reduce( ( acc, val, i ) => {
acc[ val ] = ( acc[ val ] || 0 ) + 1;
return acc;
}, {} );
},
"countOccurrences": function countOccurrences( arr, val ) {
return arr.reduce( ( a, v ) => ( v === val ? a + 1 : a + 0 ), 0 );
},
"createElement":
function createElement( str ) {
const el = document.createElement( 'div' );
el.innerHTML = str;
return el.firstElementChild;
},
"currentUrl": function currentURL() {
return window.location.href;
},
"curry":
function curry( fn, arity = fn.length, ...args ) {
return arity <= args.length ? fn( ...args ) : curry.bind( null, fn, arity, ...args );
},
"decapitalize":
function decapitalize( [ first, ...rest ], upperRest = false ) {
return first.toLowerCase() + ( upperRest ? rest.join( '' ).toUpperCase() : rest.join( '' ) );
},
"deepClone": function deepClone( obj ) {
let clone = Object.assign( {}, obj );
Object.keys( clone ).forEach(
key => ( clone[ key ] = typeof obj[ key ] === 'object' ? deepClone( obj[ key ] ) : obj[ key ] )
);
return clone;
},
"deepFlatten": function deepFlatten( arr ) {
return [].concat( ...arr.map( v => ( Array.isArray( v ) ? deepFlatten( v ) : v ) ) );
},
}
Javascript Snippets

How To Use Object Methods in JavaScript | DigitalOcean

Excerpt

Objects in JavaScript are collections of key/value pairs. The values can consist of properties and methods, and may contain all other JavaScript data types, such as strings,...


Introduction

Objects in JavaScript are collections of key/value pairs. The values can consist of properties and methods, and may contain all other JavaScript data types, such as strings, numbers, and Booleans.

All objects in JavaScript descend from the parent Object constructor. Object has many useful built-in methods we can use and access to make working with individual objects straightforward. Unlike Array prototype methods like sort() and reverse() that are used on the array instance, Object methods are used directly on the Object constructor, and use the object instance as a parameter. This is known as a static method.

This tutorial will go over important built-in object methods, with each section below dealing with a specific method and providing an example of use.

Prerequisites

In order to get the most out of this tutorial, you should be familiar with creating, modifying, and working with objects, which you can review in the “Understanding Objects in JavaScript” article.

For additional guidance on JavaScript in general, you can review our How To Code in JavaScript series.

Object.create()

The Object.create() method is used to create a new object and link it to the prototype of an existing object.

We can create a job object instance, and extend it to a more specific object.

OutputThe barista position is hourly and is accepting applications.

The barista object now has one property — position — but all the other properties and methods from job are available through the prototype. Object.create() is useful for keeping code DRY by minimizing duplication.

Object.keys()

Object.keys() creates an array containing the keys of an object.

We can create an object and print the array of keys.

Output["boss", "secretary", "sales", "accountant"]

As Object.keys converts your object’s keys into an array of keys, the forEach() array method can be used to iterate through the keys and values.

Outputboss: Michael
secretary: Pam
sales: Jim
accountant: Oscar

Object.keys is also useful for checking the length of the converted array using the length property.

Output4

Using the length property, we were able to count the 4 properties of employees.

Object.values()

Object.values() creates an array containing the values of an object.

Output[1, "26-July-2018", "mobile", "Chrome"]

Object.keys() and Object.values() allow you to return the data from an object.

Object.entries()

Object.entries() creates a nested array of the key/value pairs of an object.

Output[
    ["name", "Ubuntu"]
    ["version", 18.04]
    ["license", "Open Source"]
]

Once we have the key/value pair arrays, we can use the forEach() method to loop through and work with the results.

Outputname: Ubuntu
version: 18.04
license: Open Source

The Object.entries() method will only return the object instance’s own properties, and not any properties that may be inherited through its prototype.

Object.assign()

Object.assign() is used to copy values from one object to another.

We can create two objects, and merge them with Object.assign().

Output{firstName: "Philip", lastName: "Fry", job: "Delivery Boy", employer: "Planet Express"}

It is also possible to use the spread operator (...) to accomplish the same task. In the code below, we’ll modify how we declare character through merging the name and details objects.

Output{firstName: "Philip", lastName: "Fry", job: "Delivery Boy", employer: "Planet Express"}

This spread syntax in object literals is also known as shallow-cloning.

Object.freeze()

Object.freeze() prevents modification to properties and values of an object, and prevents properties from being added or removed from an object.

Output{username: "AzureDiamond", password: "hunter2"}

In the example above, we tried to override the password hunter2 with *******, but the password property remained the same. We also tried to add a new property, active, but it was not added.

Object.isFrozen() is available to determine whether an object has been frozen or not, and returns a Boolean.

Object.seal()

Object.seal() prevents new properties from being added to an object, but allows the modification of existing properties. This method is similar to Object.freeze(). Refresh your console before implementing the code below to avoid an error.

Output{username: "AzureDiamond", password: "*******"}

The new active property was not added to the sealed object, but the password property was successfully changed.

Object.getPrototypeOf()

Object.getPrototypeOf() is used to get the internal hidden [[Prototype]] of an object, also accessible through the __proto__ property.

In this example, we can create an array, which has access to the Array prototype.

Output[constructor: ƒ, concat: ƒ, find: ƒ, findIndex: ƒ, pop: ƒ, …]

We can see in the output that the prototype of the employees array has access to pop, find, and other Array prototype methods. We can confirm this by testing the employees prototype against Array.prototype.

Object.getPrototypeOf(employees) === Array.prototype;
Outputtrue

This method can be useful to get more information about an object or ensure it has access to the prototype of another object.

There is also a related Object.setPrototypeOf() method that will add one prototype to another object.

Conclusion

Objects have many useful methods that help us modify, protect, and iterate through them. In this tutorial, we reviewed how to create and assign new objects, iterate through the keys and/or values of an object, and freeze or seal an object.

If you need to review JavaScript objects you can read “Understanding Objects in JavaScript.” If you would like to familiarize yourself with the prototype chain, you can take a look at “Understanding Prototypes and Inheritance in JavaScript.”

title
CSVToArray

Converts a comma-separated values (CSV) string to a 2D array.

  • Use Array.prototype.slice() and Array.prototype.indexOf('\n') to remove the first row (title row) if omitFirstRow is true.
  • Use String.prototype.split('\n') to create a string for each row, then String.prototype.split(delimiter) to separate the values in each row.
  • Omit the second argument, delimiter, to use a default delimiter of ','.
  • Omit the third argument, omitFirstRow, to include the first row (title row) of the CSV string.
const CSVToArray = (data, delimiter = ',', omitFirstRow = false) =>
  data
    .slice(omitFirstRow ? data.indexOf('\n') + 1 : 0)
    .split('\n')
    .map(v => v.split(delimiter));
CSVToArray('a,b\nc,d'); // [['a', 'b'], ['c', 'd']];
CSVToArray('a;b\nc;d', ';'); // [['a', 'b'], ['c', 'd']];
CSVToArray('col1,col2\na,b\nc,d', ',', true); // [['a', 'b'], ['c', 'd']];

title: CSVToJSON

Converts a comma-separated values (CSV) string to a 2D array of objects. The first row of the string is used as the title row.

  • Use Array.prototype.slice() and Array.prototype.indexOf('\n') and String.prototype.split(delimiter) to separate the first row (title row) into values.
  • Use String.prototype.split('\n') to create a string for each row, then Array.prototype.map() and String.prototype.split(delimiter) to separate the values in each row.
  • Use Array.prototype.reduce() to create an object for each row's values, with the keys parsed from the title row.
  • Omit the second argument, delimiter, to use a default delimiter of ,.
const CSVToJSON = (data, delimiter = ',') => {
  const titles = data.slice(0, data.indexOf('\n')).split(delimiter);
  return data
    .slice(data.indexOf('\n') + 1)
    .split('\n')
    .map(v => {
      const values = v.split(delimiter);
      return titles.reduce(
        (obj, title, index) => ((obj[title] = values[index]), obj),
        {}
      );
    });
};
CSVToJSON('col1,col2\na,b\nc,d');
// [{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}];
CSVToJSON('col1;col2\na;b\nc;d', ';');
// [{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}];

title: CSVToArray

Converts a comma-separated values (CSV) string to a 2D array.

  • Use Array.prototype.slice() and Array.prototype.indexOf('\n') to remove the first row (title row) if omitFirstRow is true.
  • Use String.prototype.split('\n') to create a string for each row, then String.prototype.split(delimiter) to separate the values in each row.
  • Omit the second argument, delimiter, to use a default delimiter of ','.
  • Omit the third argument, omitFirstRow, to include the first row (title row) of the CSV string.
const CSVToArray = (data, delimiter = ',', omitFirstRow = false) =>
  data
    .slice(omitFirstRow ? data.indexOf('\n') + 1 : 0)
    .split('\n')
    .map(v => v.split(delimiter));
CSVToArray('a,b\nc,d'); // [['a', 'b'], ['c', 'd']];
CSVToArray('a;b\nc;d', ';'); // [['a', 'b'], ['c', 'd']];
CSVToArray('col1,col2\na,b\nc,d', ',', true); // [['a', 'b'], ['c', 'd']];

title: CSVToJSON

Converts a comma-separated values (CSV) string to a 2D array of objects. The first row of the string is used as the title row.

  • Use Array.prototype.slice() and Array.prototype.indexOf('\n') and String.prototype.split(delimiter) to separate the first row (title row) into values.
  • Use String.prototype.split('\n') to create a string for each row, then Array.prototype.map() and String.prototype.split(delimiter) to separate the values in each row.
  • Use Array.prototype.reduce() to create an object for each row's values, with the keys parsed from the title row.
  • Omit the second argument, delimiter, to use a default delimiter of ,.
const CSVToJSON = (data, delimiter = ',') => {
  const titles = data.slice(0, data.indexOf('\n')).split(delimiter);
  return data
    .slice(data.indexOf('\n') + 1)
    .split('\n')
    .map(v => {
      const values = v.split(delimiter);
      return titles.reduce(
        (obj, title, index) => ((obj[title] = values[index]), obj),
        {}
      );
    });
};
CSVToJSON('col1,col2\na,b\nc,d');
// [{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}];
CSVToJSON('col1;col2\na;b\nc;d', ';');
// [{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}];

title: HSBToRGB

Converts a HSB color tuple to RGB format.

  • Use the HSB to RGB conversion formula to convert to the appropriate format.
  • The range of the input parameters is H: [0, 360], S: [0, 100], B: [0, 100].
  • The range of all output values is [0, 255].
const HSBToRGB = (h, s, b) => {
  s /= 100;
  b /= 100;
  const k = (n) => (n + h / 60) % 6;
  const f = (n) => b * (1 - s * Math.max(0, Math.min(k(n), 4 - k(n), 1)));
  return [255 * f(5), 255 * f(3), 255 * f(1)];
};
HSBToRGB(18, 81, 99); // [252.45, 109.31084999999996, 47.965499999999984]

title: HSLToRGB

Converts a HSL color tuple to RGB format.

  • Use the HSL to RGB conversion formula to convert to the appropriate format.
  • The range of the input parameters is H: [0, 360], S: [0, 100], L: [0, 100].
  • The range of all output values is [0, 255].
const HSLToRGB = (h, s, l) => {
  s /= 100;
  l /= 100;
  const k = n => (n + h / 30) % 12;
  const a = s * Math.min(l, 1 - l);
  const f = n =>
    l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
  return [255 * f(0), 255 * f(8), 255 * f(4)];
};
HSLToRGB(13, 100, 11); // [56.1, 12.155, 0]

title: JSONToFile

Writes a JSON object to a file.

  • Use fs.writeFileSync(), template literals and JSON.stringify() to write a json object to a .json file.
const fs = require('fs');

const JSONToFile = (obj, filename) =>
  fs.writeFileSync(`${filename}.json`, JSON.stringify(obj, null, 2));
JSONToFile({ test: 'is passed' }, 'testJsonFile');
// writes the object to 'testJsonFile.json'

title: JSONtoCSV

Converts an array of objects to a comma-separated values (CSV) string that contains only the columns specified.

  • Use Array.prototype.join(delimiter) to combine all the names in columns to create the first row.
  • Use Array.prototype.map() and Array.prototype.reduce() to create a row for each object. Substitute non-existent values with empty strings and only mapping values in columns.
  • Use Array.prototype.join('\n') to combine all rows into a string.
  • Omit the third argument, delimiter, to use a default delimiter of ','.
const JSONtoCSV = (arr, columns, delimiter = ',') =>
  [
    columns.join(delimiter),
    ...arr.map(obj =>
      columns.reduce(
        (acc, key) =>
          `${acc}${!acc.length ? '' : delimiter}"${!obj[key] ? '' : obj[key]}"`,
        ''
      )
    ),
  ].join('\n');
JSONtoCSV(
  [{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }],
  ['a', 'b']
); // 'a,b\n"1","2"\n"3","4"\n"6",""\n"","7"'
JSONtoCSV(
  [{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }],
  ['a', 'b'],
  ';'
); // 'a;b\n"1";"2"\n"3";"4"\n"6";""\n"";"7"'

title: RGBToHSB

Converts a RGB color tuple to HSB format.

  • Use the RGB to HSB conversion formula to convert to the appropriate format.
  • The range of all input parameters is [0, 255].
  • The range of the resulting values is H: [0, 360], S: [0, 100], B: [0, 100].
const RGBToHSB = (r, g, b) => {
  r /= 255;
  g /= 255;
  b /= 255;
  const v = Math.max(r, g, b),
    n = v - Math.min(r, g, b);
  const h =
    n === 0 ? 0 : n && v === r ? (g - b) / n : v === g ? 2 + (b - r) / n : 4 + (r - g) / n;
  return [60 * (h < 0 ? h + 6 : h), v && (n / v) * 100, v * 100];
};
RGBToHSB(252, 111, 48);
// [18.529411764705856, 80.95238095238095, 98.82352941176471]

title: RGBToHSL

Converts a RGB color tuple to HSL format.

  • Use the RGB to HSL conversion formula to convert to the appropriate format.
  • The range of all input parameters is [0, 255].
  • The range of the resulting values is H: [0, 360], S: [0, 100], L: [0, 100].
const RGBToHSL = (r, g, b) => {
  r /= 255;
  g /= 255;
  b /= 255;
  const l = Math.max(r, g, b);
  const s = l - Math.min(r, g, b);
  const h = s
    ? l === r
      ? (g - b) / s
      : l === g
      ? 2 + (b - r) / s
      : 4 + (r - g) / s
    : 0;
  return [
    60 * h < 0 ? 60 * h + 360 : 60 * h,
    100 * (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0),
    (100 * (2 * l - s)) / 2,
  ];
};
RGBToHSL(45, 23, 11); // [21.17647, 60.71428, 10.98039]

title: RGBToHex

Converts the values of RGB components to a hexadecimal color code.

  • Convert given RGB parameters to hexadecimal string using bitwise left-shift operator (<<) and Number.prototype.toString(16).
  • Use String.prototype.padStart(6, '0') to get a 6-digit hexadecimal value.
const RGBToHex = (r, g, b) =>
  ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');
RGBToHex(255, 165, 1); // 'ffa501'

title: URLJoin

Joins all given URL segments together, then normalizes the resulting URL.

  • Use String.prototype.join('/') to combine URL segments.
  • Use a series of String.prototype.replace() calls with various regexps to normalize the resulting URL (remove double slashes, add proper slashes for protocol, remove slashes before parameters, combine parameters with '&' and normalize first parameter delimiter).
const URLJoin = (...args) =>
  args
    .join('/')
    .replace(/[\/]+/g, '/')
    .replace(/^(.+):\//, '$1://')
    .replace(/^file:/, 'file:/')
    .replace(/\/(\?|&|#[^!])/g, '$1')
    .replace(/\?/g, '&')
    .replace('&', '?');
URLJoin('http://www.google.com', 'a', '/b/cd', '?foo=123', '?bar=foo');
// 'http://www.google.com/a/b/cd?foo=123&bar=foo'

title: UUIDGeneratorBrowser

Generates a UUID in a browser.

  • Use Crypto.getRandomValues() to generate a UUID, compliant with RFC4122 version 4.
  • Use Number.prototype.toString(16) to convert it to a proper UUID.
const UUIDGeneratorBrowser = () =>
  ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
    (
      c ^
      (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
    ).toString(16)
  );
UUIDGeneratorBrowser(); // '7982fcfe-5721-4632-bede-6000885be57d'

title: UUIDGeneratorNode

Generates a UUID in Node.JS.

  • Use crypto.randomBytes() to generate a UUID, compliant with RFC4122 version 4.
  • Use Number.prototype.toString(16) to convert it to a proper UUID.
const crypto = require('crypto');

const UUIDGeneratorNode = () =>
  ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
    (c ^ (crypto.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16)
  );
UUIDGeneratorNode(); // '79c7c136-60ee-40a2-beb2-856f1feabefc'

title: accumulate

Creates an array of partial sums.

  • Use Array.prototype.reduce(), initialized with an empty array accumulator to iterate over nums.
  • Use Array.prototype.slice(-1), the spread operator (...) and the unary + operator to add each value to the accumulator array containing the previous sums.
const accumulate = (...nums) =>
  nums.reduce((acc, n) => [...acc, n + +acc.slice(-1)], []);
accumulate(1, 2, 3, 4); // [1, 3, 6, 10]
accumulate(...[1, 2, 3, 4]); // [1, 3, 6, 10]

title: addClass

Adds a class to an HTML element.

  • Use Element.classList and DOMTokenList.add() to add the specified class to the element.
const addClass = (el, className) => el.classList.add(className);
addClass(document.querySelector('p'), 'special');
// The paragraph will now have the 'special' class

title: addDaysToDate

Calculates the date of n days from the given date, returning its string representation.

  • Use new Date() to create a date object from the first argument.
  • Use Date.prototype.getDate() and Date.prototype.setDate() to add n days to the given date.
  • Use Date.prototype.toISOString() to return a string in yyyy-mm-dd format.
const addDaysToDate = (date, n) => {
  const d = new Date(date);
  d.setDate(d.getDate() + n);
  return d.toISOString().split('T')[0];
};
addDaysToDate('2020-10-15', 10); // '2020-10-25'
addDaysToDate('2020-10-15', -10); // '2020-10-05'

title: addEventListenerAll

Attaches an event listener to all the provided targets.

  • Use Array.prototype.forEach() and EventTarget.addEventListener() to attach the provided listener for the given event type to all targets.
const addEventListenerAll = (targets, type, listener, options, useCapture) => {
  targets.forEach(target =>
    target.addEventListener(type, listener, options, useCapture)
  );
};
addEventListenerAll(document.querySelectorAll('a'), 'click', () =>
  console.log('Clicked a link')
);
// Logs 'Clicked a link' whenever any anchor element is clicked

title: addMinutesToDate

Calculates the date of n minutes from the given date, returning its string representation.

  • Use new Date() to create a date object from the first argument.
  • Use Date.prototype.getTime() and Date.prototype.setTime() to add n minutes to the given date.
  • Use Date.prototype.toISOString(), String.prototype.split() and String.prototype.replace() to return a string in yyyy-mm-dd HH:MM:SS format.
const addMinutesToDate = (date, n) => {
  const d = new Date(date);
  d.setTime(d.getTime() + n * 60000);
  return d.toISOString().split('.')[0].replace('T',' ');
};
addMinutesToDate('2020-10-19 12:00:00', 10); // '2020-10-19 12:10:00'
addMinutesToDate('2020-10-19', -10); // '2020-10-18 23:50:00'

title: addMultipleListeners

Adds multiple event listeners with the same handler to an element.

  • Use Array.prototype.forEach() and EventTarget.addEventListener() to add multiple event listeners with an assigned callback function to an element.
const addMultipleListeners = (el, types, listener, options, useCapture) => {
  types.forEach(type =>
    el.addEventListener(type, listener, options, useCapture)
  );
};
addMultipleListeners(
  document.querySelector('.my-element'),
  ['click', 'mousedown'],
  () => { console.log('hello!') }
);

title: addStyles

Adds the provided styles to the given element.

  • Use Object.assign() and ElementCSSInlineStyle.style to merge the provided styles object into the style of the given element.
const addStyles = (el, styles) => Object.assign(el.style, styles);
addStyles(document.getElementById('my-element'), {
  background: 'red',
  color: '#ffff00',
  fontSize: '3rem'
});

title: addWeekDays

Calculates the date after adding the given number of business days.

  • Use Array.from() to construct an array with length equal to the count of business days to be added.
  • Use Array.prototype.reduce() to iterate over the array, starting from startDate and incrementing, using Date.prototype.getDate() and Date.prototype.setDate().
  • If the current date is on a weekend, update it again by adding either one day or two days to make it a weekday.
  • NOTE: Does not take official holidays into account.
const addWeekDays = (startDate, count) =>
  Array.from({ length: count }).reduce(date => {
    date = new Date(date.setDate(date.getDate() + 1));
    if (date.getDay() % 6 === 0)
      date = new Date(date.setDate(date.getDate() + (date.getDay() / 6 + 1)));
    return date;
  }, startDate);
addWeekDays(new Date('Oct 09, 2020'), 5); // 'Oct 16, 2020'
addWeekDays(new Date('Oct 12, 2020'), 5); // 'Oct 19, 2020'

title: all

Checks if the provided predicate function returns true for all elements in a collection.

  • Use Array.prototype.every() to test if all elements in the collection return true based on fn.
  • Omit the second argument, fn, to use Boolean as a default.
const all = (arr, fn = Boolean) => arr.every(fn);
all([4, 2, 3], x => x > 1); // true
all([1, 2, 3]); // true

title: allEqual

Checks if all elements in an array are equal.

  • Use Array.prototype.every() to check if all the elements of the array are the same as the first one.
  • Elements in the array are compared using the strict comparison operator, which does not account for NaN self-inequality.
const allEqual = arr => arr.every(val => val === arr[0]);
allEqual([1, 2, 3, 4, 5, 6]); // false
allEqual([1, 1, 1, 1]); // true

title: allEqualBy

Checks if all elements in an array are equal, based on the provided mapping function.

  • Apply fn to the first element of arr.
  • Use Array.prototype.every() to check if fn returns the same value for all elements in the array as it did for the first one.
  • Elements in the array are compared using the strict comparison operator, which does not account for NaN self-inequality.
const allEqualBy = (arr, fn) => {
  const eql = fn(arr[0]);
  return arr.every(val => fn(val) === eql);
};
allEqualBy([1.1, 1.2, 1.3], Math.round); // true
allEqualBy([1.1, 1.3, 1.6], Math.round); // false

title: allUnique

Checks if all elements in an array are unique.

  • Create a new Set from the mapped values to keep only unique occurrences.
  • Use Array.prototype.length and Set.prototype.size to compare the length of the unique values to the original array.
const allUnique = arr => arr.length === new Set(arr).size;
allUnique([1, 2, 3, 4]); // true
allUnique([1, 1, 2, 3]); // false

title: allUniqueBy

Checks if all elements in an array are unique, based on the provided mapping function.

  • Use Array.prototype.map() to apply fn to all elements in arr.
  • Create a new Set from the mapped values to keep only unique occurrences.
  • Use Array.prototype.length and Set.prototype.size to compare the length of the unique mapped values to the original array.
const allUniqueBy = (arr, fn) => arr.length === new Set(arr.map(fn)).size;
allUniqueBy([1.2, 2.4, 2.9], Math.round); // true
allUniqueBy([1.2, 2.3, 2.4], Math.round); // false

title: and unlisted: true

Checks if both arguments are true.

  • Use the logical and (&&) operator on the two given values.
const and = (a, b) => a && b;
and(true, true); // true
and(true, false); // false
and(false, false); // false

title: any

Checks if the provided predicate function returns true for at least one element in a collection.

  • Use Array.prototype.some() to test if any elements in the collection return true based on fn.
  • Omit the second argument, fn, to use Boolean as a default.
const any = (arr, fn = Boolean) => arr.some(fn);
any([0, 1, 2, 0], x => x >= 2); // true
any([0, 0, 1, 0]); // true

title: aperture

Creates an array of n-tuples of consecutive elements.

  • Use Array.prototype.slice() and Array.prototype.map() to create an array of appropriate length.
  • Populate the array with n-tuples of consecutive elements from arr.
  • If n is greater than the length of arr, return an empty array.
const aperture = (n, arr) =>
  n > arr.length
    ? []
    : arr.slice(n - 1).map((v, i) => arr.slice(i, i + n));
aperture(2, [1, 2, 3, 4]); // [[1, 2], [2, 3], [3, 4]]
aperture(3, [1, 2, 3, 4]); // [[1, 2, 3], [2, 3, 4]]
aperture(5, [1, 2, 3, 4]); // []

title: approximatelyEqual

Checks if two numbers are approximately equal to each other.

  • Use Math.abs() to compare the absolute difference of the two values to epsilon.
  • Omit the third argument, epsilon, to use a default value of 0.001.
const approximatelyEqual = (v1, v2, epsilon = 0.001) =>
  Math.abs(v1 - v2) < epsilon;
approximatelyEqual(Math.PI / 2.0, 1.5708); // true

title: arithmeticProgression

Creates an array of numbers in the arithmetic progression, starting with the given positive integer and up to the specified limit.

  • Use Array.from() to create an array of the desired length, lim/n. Use a map function to fill it with the desired values in the given range.
const arithmeticProgression  = (n, lim) =>
  Array.from({ length: Math.ceil(lim / n) }, (_, i) => (i + 1) * n );
arithmeticProgression(5, 25); // [5, 10, 15, 20, 25]

title: arrayToCSV

Converts a 2D array to a comma-separated values (CSV) string.

  • Use Array.prototype.map() and Array.prototype.join(delimiter) to combine individual 1D arrays (rows) into strings.
  • Use Array.prototype.join('\n') to combine all rows into a CSV string, separating each row with a newline.
  • Omit the second argument, delimiter, to use a default delimiter of ,.
const arrayToCSV = (arr, delimiter = ',') =>
  arr
    .map(v =>
      v.map(x => (isNaN(x) ? `"${x.replace(/"/g, '""')}"` : x)).join(delimiter)
    )
    .join('\n');
arrayToCSV([['a', 'b'], ['c', 'd']]); // '"a","b"\n"c","d"'
arrayToCSV([['a', 'b'], ['c', 'd']], ';'); // '"a";"b"\n"c";"d"'
arrayToCSV([['a', '"b" great'], ['c', 3.1415]]);
// '"a","""b"" great"\n"c",3.1415'

title: arrayToHTMLList

Converts the given array elements into <li> tags and appends them to the list of the given id.

  • Use Array.prototype.map() and Document.querySelector() to create a list of html tags.
const arrayToHTMLList = (arr, listID) => 
  document.querySelector(`#${listID}`).innerHTML += arr
    .map(item => `<li>${item}</li>`)
    .join('');
arrayToHTMLList(['item 1', 'item 2'], 'myListID');

title: ary

Creates a function that accepts up to n arguments, ignoring any additional arguments.

  • Call the provided function, fn, with up to n arguments, using Array.prototype.slice(0, n) and the spread operator (...).
const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
const firstTwoMax = ary(Math.max, 2);
[[2, 6, 'a'], [6, 4, 8], [10]].map(x => firstTwoMax(...x)); // [6, 6, 10]

title: assertValidKeys

Validates all keys in an object match the given keys.

  • Use Object.keys() to get the keys of the given object, obj.
  • Use Array.prototype.every() and Array.prototype.includes() to validate that each key in the object is specified in the keys array.
const assertValidKeys = (obj, keys) =>
  Object.keys(obj).every(key => keys.includes(key));
assertValidKeys({ id: 10, name: 'apple' }, ['id', 'name']); // true
assertValidKeys({ id: 10, name: 'apple' }, ['id', 'type']); // false

title: atob

Decodes a string of data which has been encoded using base-64 encoding.

  • Create a Buffer for the given string with base-64 encoding and use Buffer.toString('binary') to return the decoded string.
const atob = str => Buffer.from(str, 'base64').toString('binary');
atob('Zm9vYmFy'); // 'foobar'

title: attempt

Attempts to invoke a function with the provided arguments, returning either the result or the caught error object.

  • Use a try... catch block to return either the result of the function or an appropriate error.
  • If the caught object is not an Error, use it to create a new Error.
const attempt = (fn, ...args) => {
  try {
    return fn(...args);
  } catch (e) {
    return e instanceof Error ? e : new Error(e);
  }
};
let elements = attempt(function(selector) {
  return document.querySelectorAll(selector);
}, '>_>');
if (elements instanceof Error) elements = []; // elements = []

title: average

Calculates the average of two or more numbers.

  • Use Array.prototype.reduce() to add each value to an accumulator, initialized with a value of 0.
  • Divide the resulting array by its length.
const average = (...nums) =>
  nums.reduce((acc, val) => acc + val, 0) / nums.length;
average(...[1, 2, 3]); // 2
average(1, 2, 3); // 2

title: averageBy

Calculates the average of an array, after mapping each element to a value using the provided function.

  • Use Array.prototype.map() to map each element to the value returned by fn.
  • Use Array.prototype.reduce() to add each value to an accumulator, initialized with a value of 0.
  • Divide the resulting array by its length.
const averageBy = (arr, fn) =>
  arr
    .map(typeof fn === 'function' ? fn : val => val[fn])
    .reduce((acc, val) => acc + val, 0) / arr.length;
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 5
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 5

title: bifurcate

Splits values into two groups, based on the result of the given filter array.

  • Use Array.prototype.reduce() and Array.prototype.push() to add elements to groups, based on filter.
  • If filter has a truthy value for any element, add it to the first group, otherwise add it to the second group.
const bifurcate = (arr, filter) =>
  arr.reduce((acc, val, i) => (acc[filter[i] ? 0 : 1].push(val), acc), [
    [],
    [],
  ]);
bifurcate(['beep', 'boop', 'foo', 'bar'], [true, true, false, true]);
// [ ['beep', 'boop', 'bar'], ['foo'] ]

title: bifurcateBy

Splits values into two groups, based on the result of the given filtering function.

  • Use Array.prototype.reduce() and Array.prototype.push() to add elements to groups, based on the value returned by fn for each element.
  • If fn returns a truthy value for any element, add it to the first group, otherwise add it to the second group.
const bifurcateBy = (arr, fn) =>
  arr.reduce((acc, val, i) => (acc[fn(val, i) ? 0 : 1].push(val), acc), [
    [],
    [],
  ]);
bifurcateBy(['beep', 'boop', 'foo', 'bar'], x => x[0] === 'b');
// [ ['beep', 'boop', 'bar'], ['foo'] ]

title: binary

Creates a function that accepts up to two arguments, ignoring any additional arguments.

  • Call the provided function, fn, with the first two arguments given.
const binary = fn => (a, b) => fn(a, b);
['2', '1', '0'].map(binary(Math.max)); // [2, 1, 2]

title: binarySearch

Finds the index of a given element in a sorted array using the binary search algorithm.

  • Declare the left and right search boundaries, l and r, initialized to 0 and the length of the array respectively.
  • Use a while loop to repeatedly narrow down the search subarray, using Math.floor() to cut it in half.
  • Return the index of the element if found, otherwise return -1.
  • Note: Does not account for duplicate values in the array.
const binarySearch = (arr, item) => {
  let l = 0,
    r = arr.length - 1;
  while (l <= r) {
    const mid = Math.floor((l + r) / 2);
    const guess = arr[mid];
    if (guess === item) return mid;
    if (guess > item) r = mid - 1;
    else l = mid + 1;
  }
  return -1;
};
binarySearch([1, 2, 3, 4, 5], 1); // 0
binarySearch([1, 2, 3, 4, 5], 5); // 4
binarySearch([1, 2, 3, 4, 5], 6); // -1

title: bind

Creates a function that invokes fn with a given context, optionally prepending any additional supplied parameters to the arguments.

  • Return a function that uses Function.prototype.apply() to apply the given context to fn.
  • Use the spread operator (...) to prepend any additional supplied parameters to the arguments.
const bind = (fn, context, ...boundArgs) => (...args) =>
  fn.apply(context, [...boundArgs, ...args]);
function greet(greeting, punctuation) {
  return greeting + ' ' + this.user + punctuation;
}
const freddy = { user: 'fred' };
const freddyBound = bind(greet, freddy);
console.log(freddyBound('hi', '!')); // 'hi fred!'

title: bindAll

Binds methods of an object to the object itself, overwriting the existing method.

  • Use Array.prototype.forEach() to iterate over the given fns.
  • Return a function for each one, using Function.prototype.apply() to apply the given context (obj) to fn.
const bindAll = (obj, ...fns) =>
  fns.forEach(
    fn => (
      (f = obj[fn]),
      (obj[fn] = function() {
        return f.apply(obj);
      })
    )
  );
let view = {
  label: 'docs',
  click: function() {
    console.log('clicked ' + this.label);
  }
};
bindAll(view, 'click');
document.body.addEventListener('click', view.click);
// Log 'clicked docs' when clicked.

title: bindKey

Creates a function that invokes the method at a given key of an object, optionally prepending any additional supplied parameters to the arguments.

  • Return a function that uses Function.prototype.apply() to bind context[fn] to context.
  • Use the spread operator (...) to prepend any additional supplied parameters to the arguments.
const bindKey = (context, fn, ...boundArgs) => (...args) =>
  context[fn].apply(context, [...boundArgs, ...args]);
const freddy = {
  user: 'fred',
  greet: function(greeting, punctuation) {
    return greeting + ' ' + this.user + punctuation;
  }
};
const freddyBound = bindKey(freddy, 'greet');
console.log(freddyBound('hi', '!')); // 'hi fred!'

title: binomialCoefficient

Calculates the number of ways to choose k items from n items without repetition and without order.

  • Use Number.isNaN() to check if any of the two values is NaN.
  • Check if k is less than 0, greater than or equal to n, equal to 1 or n - 1 and return the appropriate result.
  • Check if n - k is less than k and switch their values accordingly.
  • Loop from 2 through k and calculate the binomial coefficient.
  • Use Math.round() to account for rounding errors in the calculation.
const binomialCoefficient = (n, k) => {
  if (Number.isNaN(n) || Number.isNaN(k)) return NaN;
  if (k < 0 || k > n) return 0;
  if (k === 0 || k === n) return 1;
  if (k === 1 || k === n - 1) return n;
  if (n - k < k) k = n - k;
  let res = n;
  for (let j = 2; j <= k; j++) res *= (n - j + 1) / j;
  return Math.round(res);
};
binomialCoefficient(8, 2); // 28

title: both unlisted: true

Checks if both of the given functions return true for a given set of arguments.

  • Use the logical and (&&) operator on the result of calling the two functions with the supplied args.
const both = (f, g) => (...args) => f(...args) && g(...args);
const isEven = num => num % 2 === 0;
const isPositive = num => num > 0;
const isPositiveEven = both(isEven, isPositive);
isPositiveEven(4); // true
isPositiveEven(-2); // false

title: HSBToRGB

Converts a HSB color tuple to RGB format.

  • Use the HSB to RGB conversion formula to convert to the appropriate format.
  • The range of the input parameters is H: [0, 360], S: [0, 100], B: [0, 100].
  • The range of all output values is [0, 255].
const HSBToRGB = (h, s, b) => {
  s /= 100;
  b /= 100;
  const k = (n) => (n + h / 60) % 6;
  const f = (n) => b * (1 - s * Math.max(0, Math.min(k(n), 4 - k(n), 1)));
  return [255 * f(5), 255 * f(3), 255 * f(1)];
};
HSBToRGB(18, 81, 99); // [252.45, 109.31084999999996, 47.965499999999984]

title: HSLToRGB

Converts a HSL color tuple to RGB format.

  • Use the HSL to RGB conversion formula to convert to the appropriate format.
  • The range of the input parameters is H: [0, 360], S: [0, 100], L: [0, 100].
  • The range of all output values is [0, 255].
const HSLToRGB = (h, s, l) => {
  s /= 100;
  l /= 100;
  const k = n => (n + h / 30) % 12;
  const a = s * Math.min(l, 1 - l);
  const f = n =>
    l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
  return [255 * f(0), 255 * f(8), 255 * f(4)];
};
HSLToRGB(13, 100, 11); // [56.1, 12.155, 0]

title: JSONToFile

Writes a JSON object to a file.

  • Use fs.writeFileSync(), template literals and JSON.stringify() to write a json object to a .json file.
const fs = require('fs');

const JSONToFile = (obj, filename) =>
  fs.writeFileSync(`${filename}.json`, JSON.stringify(obj, null, 2));
JSONToFile({ test: 'is passed' }, 'testJsonFile');
// writes the object to 'testJsonFile.json'

title: JSONtoCSV

Converts an array of objects to a comma-separated values (CSV) string that contains only the columns specified.

  • Use Array.prototype.join(delimiter) to combine all the names in columns to create the first row.
  • Use Array.prototype.map() and Array.prototype.reduce() to create a row for each object. Substitute non-existent values with empty strings and only mapping values in columns.
  • Use Array.prototype.join('\n') to combine all rows into a string.
  • Omit the third argument, delimiter, to use a default delimiter of ','.
const JSONtoCSV = (arr, columns, delimiter = ',') =>
  [
    columns.join(delimiter),
    ...arr.map(obj =>
      columns.reduce(
        (acc, key) =>
          `${acc}${!acc.length ? '' : delimiter}"${!obj[key] ? '' : obj[key]}"`,
        ''
      )
    ),
  ].join('\n');
JSONtoCSV(
  [{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }],
  ['a', 'b']
); // 'a,b\n"1","2"\n"3","4"\n"6",""\n"","7"'
JSONtoCSV(
  [{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }],
  ['a', 'b'],
  ';'
); // 'a;b\n"1";"2"\n"3";"4"\n"6";""\n"";"7"'

title: RGBToHSB

Converts a RGB color tuple to HSB format.

  • Use the RGB to HSB conversion formula to convert to the appropriate format.
  • The range of all input parameters is [0, 255].
  • The range of the resulting values is H: [0, 360], S: [0, 100], B: [0, 100].
const RGBToHSB = (r, g, b) => {
  r /= 255;
  g /= 255;
  b /= 255;
  const v = Math.max(r, g, b),
    n = v - Math.min(r, g, b);
  const h =
    n === 0 ? 0 : n && v === r ? (g - b) / n : v === g ? 2 + (b - r) / n : 4 + (r - g) / n;
  return [60 * (h < 0 ? h + 6 : h), v && (n / v) * 100, v * 100];
};
RGBToHSB(252, 111, 48);
// [18.529411764705856, 80.95238095238095, 98.82352941176471]

title: RGBToHSL

Converts a RGB color tuple to HSL format.

  • Use the RGB to HSL conversion formula to convert to the appropriate format.
  • The range of all input parameters is [0, 255].
  • The range of the resulting values is H: [0, 360], S: [0, 100], L: [0, 100].
const RGBToHSL = (r, g, b) => {
  r /= 255;
  g /= 255;
  b /= 255;
  const l = Math.max(r, g, b);
  const s = l - Math.min(r, g, b);
  const h = s
    ? l === r
      ? (g - b) / s
      : l === g
      ? 2 + (b - r) / s
      : 4 + (r - g) / s
    : 0;
  return [
    60 * h < 0 ? 60 * h + 360 : 60 * h,
    100 * (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0),
    (100 * (2 * l - s)) / 2,
  ];
};
RGBToHSL(45, 23, 11); // [21.17647, 60.71428, 10.98039]

title: RGBToHex

Converts the values of RGB components to a hexadecimal color code.

  • Convert given RGB parameters to hexadecimal string using bitwise left-shift operator (<<) and Number.prototype.toString(16).
  • Use String.prototype.padStart(6, '0') to get a 6-digit hexadecimal value.
const RGBToHex = (r, g, b) =>
  ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');
RGBToHex(255, 165, 1); // 'ffa501'

title: URLJoin

Joins all given URL segments together, then normalizes the resulting URL.

  • Use String.prototype.join('/') to combine URL segments.
  • Use a series of String.prototype.replace() calls with various regexps to normalize the resulting URL (remove double slashes, add proper slashes for protocol, remove slashes before parameters, combine parameters with '&' and normalize first parameter delimiter).
const URLJoin = (...args) =>
  args
    .join('/')
    .replace(/[\/]+/g, '/')
    .replace(/^(.+):\//, '$1://')
    .replace(/^file:/, 'file:/')
    .replace(/\/(\?|&|#[^!])/g, '$1')
    .replace(/\?/g, '&')
    .replace('&', '?');
URLJoin('http://www.google.com', 'a', '/b/cd', '?foo=123', '?bar=foo');
// 'http://www.google.com/a/b/cd?foo=123&bar=foo'

title: UUIDGeneratorBrowser

Generates a UUID in a browser.

  • Use Crypto.getRandomValues() to generate a UUID, compliant with RFC4122 version 4.
  • Use Number.prototype.toString(16) to convert it to a proper UUID.
const UUIDGeneratorBrowser = () =>
  ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
    (
      c ^
      (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
    ).toString(16)
  );
UUIDGeneratorBrowser(); // '7982fcfe-5721-4632-bede-6000885be57d'

title: UUIDGeneratorNode

Generates a UUID in Node.JS.

  • Use crypto.randomBytes() to generate a UUID, compliant with RFC4122 version 4.
  • Use Number.prototype.toString(16) to convert it to a proper UUID.
const crypto = require('crypto');

const UUIDGeneratorNode = () =>
  ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
    (c ^ (crypto.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16)
  );
UUIDGeneratorNode(); // '79c7c136-60ee-40a2-beb2-856f1feabefc'

title: accumulate

Creates an array of partial sums.

  • Use Array.prototype.reduce(), initialized with an empty array accumulator to iterate over nums.
  • Use Array.prototype.slice(-1), the spread operator (...) and the unary + operator to add each value to the accumulator array containing the previous sums.
const accumulate = (...nums) =>
  nums.reduce((acc, n) => [...acc, n + +acc.slice(-1)], []);
accumulate(1, 2, 3, 4); // [1, 3, 6, 10]
accumulate(...[1, 2, 3, 4]); // [1, 3, 6, 10]

title: addClass

Adds a class to an HTML element.

  • Use Element.classList and DOMTokenList.add() to add the specified class to the element.
const addClass = (el, className) => el.classList.add(className);
addClass(document.querySelector('p'), 'special');
// The paragraph will now have the 'special' class

title: addDaysToDate

Calculates the date of n days from the given date, returning its string representation.

  • Use new Date() to create a date object from the first argument.
  • Use Date.prototype.getDate() and Date.prototype.setDate() to add n days to the given date.
  • Use Date.prototype.toISOString() to return a string in yyyy-mm-dd format.
const addDaysToDate = (date, n) => {
  const d = new Date(date);
  d.setDate(d.getDate() + n);
  return d.toISOString().split('T')[0];
};
addDaysToDate('2020-10-15', 10); // '2020-10-25'
addDaysToDate('2020-10-15', -10); // '2020-10-05'

title: addEventListenerAll

Attaches an event listener to all the provided targets.

  • Use Array.prototype.forEach() and EventTarget.addEventListener() to attach the provided listener for the given event type to all targets.
const addEventListenerAll = (targets, type, listener, options, useCapture) => {
  targets.forEach(target =>
    target.addEventListener(type, listener, options, useCapture)
  );
};
addEventListenerAll(document.querySelectorAll('a'), 'click', () =>
  console.log('Clicked a link')
);
// Logs 'Clicked a link' whenever any anchor element is clicked

title: addMinutesToDate

Calculates the date of n minutes from the given date, returning its string representation.

  • Use new Date() to create a date object from the first argument.
  • Use Date.prototype.getTime() and Date.prototype.setTime() to add n minutes to the given date.
  • Use Date.prototype.toISOString(), String.prototype.split() and String.prototype.replace() to return a string in yyyy-mm-dd HH:MM:SS format.
const addMinutesToDate = (date, n) => {
  const d = new Date(date);
  d.setTime(d.getTime() + n * 60000);
  return d.toISOString().split('.')[0].replace('T',' ');
};
addMinutesToDate('2020-10-19 12:00:00', 10); // '2020-10-19 12:10:00'
addMinutesToDate('2020-10-19', -10); // '2020-10-18 23:50:00'

title: addMultipleListeners

Adds multiple event listeners with the same handler to an element.

  • Use Array.prototype.forEach() and EventTarget.addEventListener() to add multiple event listeners with an assigned callback function to an element.
const addMultipleListeners = (el, types, listener, options, useCapture) => {
  types.forEach(type =>
    el.addEventListener(type, listener, options, useCapture)
  );
};
addMultipleListeners(
  document.querySelector('.my-element'),
  ['click', 'mousedown'],
  () => { console.log('hello!') }
);

title: addStyles

Adds the provided styles to the given element.

  • Use Object.assign() and ElementCSSInlineStyle.style to merge the provided styles object into the style of the given element.
const addStyles = (el, styles) => Object.assign(el.style, styles);
addStyles(document.getElementById('my-element'), {
  background: 'red',
  color: '#ffff00',
  fontSize: '3rem'
});

title: addWeekDays

Calculates the date after adding the given number of business days.

  • Use Array.from() to construct an array with length equal to the count of business days to be added.
  • Use Array.prototype.reduce() to iterate over the array, starting from startDate and incrementing, using Date.prototype.getDate() and Date.prototype.setDate().
  • If the current date is on a weekend, update it again by adding either one day or two days to make it a weekday.
  • NOTE: Does not take official holidays into account.
const addWeekDays = (startDate, count) =>
  Array.from({ length: count }).reduce(date => {
    date = new Date(date.setDate(date.getDate() + 1));
    if (date.getDay() % 6 === 0)
      date = new Date(date.setDate(date.getDate() + (date.getDay() / 6 + 1)));
    return date;
  }, startDate);
addWeekDays(new Date('Oct 09, 2020'), 5); // 'Oct 16, 2020'
addWeekDays(new Date('Oct 12, 2020'), 5); // 'Oct 19, 2020'

title: all

Checks if the provided predicate function returns true for all elements in a collection.

  • Use Array.prototype.every() to test if all elements in the collection return true based on fn.
  • Omit the second argument, fn, to use Boolean as a default.
const all = (arr, fn = Boolean) => arr.every(fn);
all([4, 2, 3], x => x > 1); // true
all([1, 2, 3]); // true

title: allEqual

Checks if all elements in an array are equal.

  • Use Array.prototype.every() to check if all the elements of the array are the same as the first one.
  • Elements in the array are compared using the strict comparison operator, which does not account for NaN self-inequality.
const allEqual = arr => arr.every(val => val === arr[0]);
allEqual([1, 2, 3, 4, 5, 6]); // false
allEqual([1, 1, 1, 1]); // true

title: allEqualBy

Checks if all elements in an array are equal, based on the provided mapping function.

  • Apply fn to the first element of arr.
  • Use Array.prototype.every() to check if fn returns the same value for all elements in the array as it did for the first one.
  • Elements in the array are compared using the strict comparison operator, which does not account for NaN self-inequality.
const allEqualBy = (arr, fn) => {
  const eql = fn(arr[0]);
  return arr.every(val => fn(val) === eql);
};
allEqualBy([1.1, 1.2, 1.3], Math.round); // true
allEqualBy([1.1, 1.3, 1.6], Math.round); // false

title: allUnique

Checks if all elements in an array are unique.

  • Create a new Set from the mapped values to keep only unique occurrences.
  • Use Array.prototype.length and Set.prototype.size to compare the length of the unique values to the original array.
const allUnique = arr => arr.length === new Set(arr).size;
allUnique([1, 2, 3, 4]); // true
allUnique([1, 1, 2, 3]); // false

title: allUniqueBy

Checks if all elements in an array are unique, based on the provided mapping function.

  • Use Array.prototype.map() to apply fn to all elements in arr.
  • Create a new Set from the mapped values to keep only unique occurrences.
  • Use Array.prototype.length and Set.prototype.size to compare the length of the unique mapped values to the original array.
const allUniqueBy = (arr, fn) => arr.length === new Set(arr.map(fn)).size;
allUniqueBy([1.2, 2.4, 2.9], Math.round); // true
allUniqueBy([1.2, 2.3, 2.4], Math.round); // false

title: and unlisted: true

Checks if both arguments are true.

  • Use the logical and (&&) operator on the two given values.
const and = (a, b) => a && b;
and(true, true); // true
and(true, false); // false
and(false, false); // false

title: any

Checks if the provided predicate function returns true for at least one element in a collection.

  • Use Array.prototype.some() to test if any elements in the collection return true based on fn.
  • Omit the second argument, fn, to use Boolean as a default.
const any = (arr, fn = Boolean) => arr.some(fn);
any([0, 1, 2, 0], x => x >= 2); // true
any([0, 0, 1, 0]); // true

title: aperture

Creates an array of n-tuples of consecutive elements.

  • Use Array.prototype.slice() and Array.prototype.map() to create an array of appropriate length.
  • Populate the array with n-tuples of consecutive elements from arr.
  • If n is greater than the length of arr, return an empty array.
const aperture = (n, arr) =>
  n > arr.length
    ? []
    : arr.slice(n - 1).map((v, i) => arr.slice(i, i + n));
aperture(2, [1, 2, 3, 4]); // [[1, 2], [2, 3], [3, 4]]
aperture(3, [1, 2, 3, 4]); // [[1, 2, 3], [2, 3, 4]]
aperture(5, [1, 2, 3, 4]); // []

title: approximatelyEqual

Checks if two numbers are approximately equal to each other.

  • Use Math.abs() to compare the absolute difference of the two values to epsilon.
  • Omit the third argument, epsilon, to use a default value of 0.001.
const approximatelyEqual = (v1, v2, epsilon = 0.001) =>
  Math.abs(v1 - v2) < epsilon;
approximatelyEqual(Math.PI / 2.0, 1.5708); // true

title: arithmeticProgression

Creates an array of numbers in the arithmetic progression, starting with the given positive integer and up to the specified limit.

  • Use Array.from() to create an array of the desired length, lim/n. Use a map function to fill it with the desired values in the given range.
const arithmeticProgression  = (n, lim) =>
  Array.from({ length: Math.ceil(lim / n) }, (_, i) => (i + 1) * n );
arithmeticProgression(5, 25); // [5, 10, 15, 20, 25]

title: arrayToCSV

Converts a 2D array to a comma-separated values (CSV) string.

  • Use Array.prototype.map() and Array.prototype.join(delimiter) to combine individual 1D arrays (rows) into strings.
  • Use Array.prototype.join('\n') to combine all rows into a CSV string, separating each row with a newline.
  • Omit the second argument, delimiter, to use a default delimiter of ,.
const arrayToCSV = (arr, delimiter = ',') =>
  arr
    .map(v =>
      v.map(x => (isNaN(x) ? `"${x.replace(/"/g, '""')}"` : x)).join(delimiter)
    )
    .join('\n');
arrayToCSV([['a', 'b'], ['c', 'd']]); // '"a","b"\n"c","d"'
arrayToCSV([['a', 'b'], ['c', 'd']], ';'); // '"a";"b"\n"c";"d"'
arrayToCSV([['a', '"b" great'], ['c', 3.1415]]);
// '"a","""b"" great"\n"c",3.1415'

title: arrayToHTMLList

Converts the given array elements into <li> tags and appends them to the list of the given id.

  • Use Array.prototype.map() and Document.querySelector() to create a list of html tags.
const arrayToHTMLList = (arr, listID) => 
  document.querySelector(`#${listID}`).innerHTML += arr
    .map(item => `<li>${item}</li>`)
    .join('');
arrayToHTMLList(['item 1', 'item 2'], 'myListID');

title: ary

Creates a function that accepts up to n arguments, ignoring any additional arguments.

  • Call the provided function, fn, with up to n arguments, using Array.prototype.slice(0, n) and the spread operator (...).
const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
const firstTwoMax = ary(Math.max, 2);
[[2, 6, 'a'], [6, 4, 8], [10]].map(x => firstTwoMax(...x)); // [6, 6, 10]

title: assertValidKeys

Validates all keys in an object match the given keys.

  • Use Object.keys() to get the keys of the given object, obj.
  • Use Array.prototype.every() and Array.prototype.includes() to validate that each key in the object is specified in the keys array.
const assertValidKeys = (obj, keys) =>
  Object.keys(obj).every(key => keys.includes(key));
assertValidKeys({ id: 10, name: 'apple' }, ['id', 'name']); // true
assertValidKeys({ id: 10, name: 'apple' }, ['id', 'type']); // false

title: atob

Decodes a string of data which has been encoded using base-64 encoding.

  • Create a Buffer for the given string with base-64 encoding and use Buffer.toString('binary') to return the decoded string.
const atob = str => Buffer.from(str, 'base64').toString('binary');
atob('Zm9vYmFy'); // 'foobar'

title: attempt

Attempts to invoke a function with the provided arguments, returning either the result or the caught error object.

  • Use a try... catch block to return either the result of the function or an appropriate error.
  • If the caught object is not an Error, use it to create a new Error.
const attempt = (fn, ...args) => {
  try {
    return fn(...args);
  } catch (e) {
    return e instanceof Error ? e : new Error(e);
  }
};
let elements = attempt(function(selector) {
  return document.querySelectorAll(selector);
}, '>_>');
if (elements instanceof Error) elements = []; // elements = []

title: average

Calculates the average of two or more numbers.

  • Use Array.prototype.reduce() to add each value to an accumulator, initialized with a value of 0.
  • Divide the resulting array by its length.
const average = (...nums) =>
  nums.reduce((acc, val) => acc + val, 0) / nums.length;
average(...[1, 2, 3]); // 2
average(1, 2, 3); // 2

title: averageBy

Calculates the average of an array, after mapping each element to a value using the provided function.

  • Use Array.prototype.map() to map each element to the value returned by fn.
  • Use Array.prototype.reduce() to add each value to an accumulator, initialized with a value of 0.
  • Divide the resulting array by its length.
const averageBy = (arr, fn) =>
  arr
    .map(typeof fn === 'function' ? fn : val => val[fn])
    .reduce((acc, val) => acc + val, 0) / arr.length;
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 5
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 5

title: bifurcate

Splits values into two groups, based on the result of the given filter array.

  • Use Array.prototype.reduce() and Array.prototype.push() to add elements to groups, based on filter.
  • If filter has a truthy value for any element, add it to the first group, otherwise add it to the second group.
const bifurcate = (arr, filter) =>
  arr.reduce((acc, val, i) => (acc[filter[i] ? 0 : 1].push(val), acc), [
    [],
    [],
  ]);
bifurcate(['beep', 'boop', 'foo', 'bar'], [true, true, false, true]);
// [ ['beep', 'boop', 'bar'], ['foo'] ]

title: bifurcateBy

Splits values into two groups, based on the result of the given filtering function.

  • Use Array.prototype.reduce() and Array.prototype.push() to add elements to groups, based on the value returned by fn for each element.
  • If fn returns a truthy value for any element, add it to the first group, otherwise add it to the second group.
const bifurcateBy = (arr, fn) =>
  arr.reduce((acc, val, i) => (acc[fn(val, i) ? 0 : 1].push(val), acc), [
    [],
    [],
  ]);
bifurcateBy(['beep', 'boop', 'foo', 'bar'], x => x[0] === 'b');
// [ ['beep', 'boop', 'bar'], ['foo'] ]

title: binary

Creates a function that accepts up to two arguments, ignoring any additional arguments.

  • Call the provided function, fn, with the first two arguments given.
const binary = fn => (a, b) => fn(a, b);
['2', '1', '0'].map(binary(Math.max)); // [2, 1, 2]

title: binarySearch

Finds the index of a given element in a sorted array using the binary search algorithm.

  • Declare the left and right search boundaries, l and r, initialized to 0 and the length of the array respectively.
  • Use a while loop to repeatedly narrow down the search subarray, using Math.floor() to cut it in half.
  • Return the index of the element if found, otherwise return -1.
  • Note: Does not account for duplicate values in the array.
const binarySearch = (arr, item) => {
  let l = 0,
    r = arr.length - 1;
  while (l <= r) {
    const mid = Math.floor((l + r) / 2);
    const guess = arr[mid];
    if (guess === item) return mid;
    if (guess > item) r = mid - 1;
    else l = mid + 1;
  }
  return -1;
};
binarySearch([1, 2, 3, 4, 5], 1); // 0
binarySearch([1, 2, 3, 4, 5], 5); // 4
binarySearch([1, 2, 3, 4, 5], 6); // -1

title: bind

Creates a function that invokes fn with a given context, optionally prepending any additional supplied parameters to the arguments.

  • Return a function that uses Function.prototype.apply() to apply the given context to fn.
  • Use the spread operator (...) to prepend any additional supplied parameters to the arguments.
const bind = (fn, context, ...boundArgs) => (...args) =>
  fn.apply(context, [...boundArgs, ...args]);
function greet(greeting, punctuation) {
  return greeting + ' ' + this.user + punctuation;
}
const freddy = { user: 'fred' };
const freddyBound = bind(greet, freddy);
console.log(freddyBound('hi', '!')); // 'hi fred!'

title: bindAll

Binds methods of an object to the object itself, overwriting the existing method.

  • Use Array.prototype.forEach() to iterate over the given fns.
  • Return a function for each one, using Function.prototype.apply() to apply the given context (obj) to fn.
const bindAll = (obj, ...fns) =>
  fns.forEach(
    fn => (
      (f = obj[fn]),
      (obj[fn] = function() {
        return f.apply(obj);
      })
    )
  );
let view = {
  label: 'docs',
  click: function() {
    console.log('clicked ' + this.label);
  }
};
bindAll(view, 'click');
document.body.addEventListener('click', view.click);
// Log 'clicked docs' when clicked.

title: bindKey

Creates a function that invokes the method at a given key of an object, optionally prepending any additional supplied parameters to the arguments.

  • Return a function that uses Function.prototype.apply() to bind context[fn] to context.
  • Use the spread operator (...) to prepend any additional supplied parameters to the arguments.
const bindKey = (context, fn, ...boundArgs) => (...args) =>
  context[fn].apply(context, [...boundArgs, ...args]);
const freddy = {
  user: 'fred',
  greet: function(greeting, punctuation) {
    return greeting + ' ' + this.user + punctuation;
  }
};
const freddyBound = bindKey(freddy, 'greet');
console.log(freddyBound('hi', '!')); // 'hi fred!'

title: binomialCoefficient

Calculates the number of ways to choose k items from n items without repetition and without order.

  • Use Number.isNaN() to check if any of the two values is NaN.
  • Check if k is less than 0, greater than or equal to n, equal to 1 or n - 1 and return the appropriate result.
  • Check if n - k is less than k and switch their values accordingly.
  • Loop from 2 through k and calculate the binomial coefficient.
  • Use Math.round() to account for rounding errors in the calculation.
const binomialCoefficient = (n, k) => {
  if (Number.isNaN(n) || Number.isNaN(k)) return NaN;
  if (k < 0 || k > n) return 0;
  if (k === 0 || k === n) return 1;
  if (k === 1 || k === n - 1) return n;
  if (n - k < k) k = n - k;
  let res = n;
  for (let j = 2; j <= k; j++) res *= (n - j + 1) / j;
  return Math.round(res);
};
binomialCoefficient(8, 2); // 28

title: both unlisted: true

Checks if both of the given functions return true for a given set of arguments.

  • Use the logical and (&&) operator on the result of calling the two functions with the supplied args.
const both = (f, g) => (...args) => f(...args) && g(...args);
const isEven = num => num % 2 === 0;
const isPositive = num => num > 0;
const isPositiveEven = both(isEven, isPositive);
isPositiveEven(4); // true
isPositiveEven(-2); // false

title: btoa

Creates a base-64 encoded ASCII string from a String object in which each character in the string is treated as a byte of binary data.

  • Create a Buffer for the given string with binary encoding and use Buffer.toString('base64') to return the encoded string.
const btoa = str => Buffer.from(str, 'binary').toString('base64');
btoa('foobar'); // 'Zm9vYmFy'

title: bubbleSort

Sorts an array of numbers, using the bubble sort algorithm.

  • Declare a variable, swapped, that indicates if any values were swapped during the current iteration.
  • Use the spread operator (...) to clone the original array, arr.
  • Use a for loop to iterate over the elements of the cloned array, terminating before the last element.
  • Use a nested for loop to iterate over the segment of the array between 0 and i, swapping any adjacent out of order elements and setting swapped to true.
  • If swapped is false after an iteration, no more changes are needed, so the cloned array is returned.
const bubbleSort = arr => {
  let swapped = false;
  const a = [...arr];
  for (let i = 1; i < a.length; i++) {
    swapped = false;
    for (let j = 0; j < a.length - i; j++) {
      if (a[j + 1] < a[j]) {
        [a[j], a[j + 1]] = [a[j + 1], a[j]];
        swapped = true;
      }
    }
    if (!swapped) return a;
  }
  return a;
};
bubbleSort([2, 1, 4, 3]); // [1, 2, 3, 4]

title: bucketSort

Sorts an array of numbers, using the bucket sort algorithm.

  • Use Math.min(), Math.max() and the spread operator (...) to find the minimum and maximum values of the given array.
  • Use Array.from() and Math.floor() to create the appropriate number of buckets (empty arrays).
  • Use Array.prototype.forEach() to populate each bucket with the appropriate elements from the array.
  • Use Array.prototype.reduce(), the spread operator (...) and Array.prototype.sort() to sort each bucket and append it to the result.
const bucketSort = (arr, size = 5) => {
  const min = Math.min(...arr);
  const max = Math.max(...arr);
  const buckets = Array.from(
    { length: Math.floor((max - min) / size) + 1 },
    () => []
  );
  arr.forEach(val => {
    buckets[Math.floor((val - min) / size)].push(val);
  });
  return buckets.reduce((acc, b) => [...acc, ...b.sort((a, b) => a - b)], []);
};
bucketSort([6, 3, 4, 1]); // [1, 3, 4, 6]

title: byteSize

Returns the length of a string in bytes.

  • Convert a given string to a Blob Object.
  • Use Blob.size to get the length of the string in bytes.
const byteSize = str => new Blob([str]).size;
byteSize('😀'); // 4
byteSize('Hello World'); // 11

title: caesarCipher

Encrypts or decrypts a given string using the Caesar cipher.

  • Use the modulo (%) operator and the ternary operator (?) to calculate the correct encryption/decryption key.
  • Use the spread operator (...) and Array.prototype.map() to iterate over the letters of the given string.
  • Use String.prototype.charCodeAt() and String.fromCharCode() to convert each letter appropriately, ignoring special characters, spaces etc.
  • Use Array.prototype.join() to combine all the letters into a string.
  • Pass true to the last parameter, decrypt, to decrypt an encrypted string.
const caesarCipher = (str, shift, decrypt = false) => {
  const s = decrypt ? (26 - shift) % 26 : shift;
  const n = s > 0 ? s : 26 + (s % 26);
  return [...str]
    .map((l, i) => {
      const c = str.charCodeAt(i);
      if (c >= 65 && c <= 90)
        return String.fromCharCode(((c - 65 + n) % 26) + 65);
      if (c >= 97 && c <= 122)
        return String.fromCharCode(((c - 97 + n) % 26) + 97);
      return l;
    })
    .join('');
};
caesarCipher('Hello World!', -3); // 'Ebiil Tloia!'
caesarCipher('Ebiil Tloia!', 23, true); // 'Hello World!'

title: call

Given a key and a set of arguments, call them when given a context.

  • Use a closure to call key with args for the given context.
const call = (key, ...args) => context => context[key](...args);
Promise.resolve([1, 2, 3])
  .then(call('map', x => 2 * x))
  .then(console.log); // [ 2, 4, 6 ]
const map = call.bind(null, 'map');
Promise.resolve([1, 2, 3])
  .then(map(x => 2 * x))
  .then(console.log); // [ 2, 4, 6 ]

title: capitalize

Capitalizes the first letter of a string.

  • Use array destructuring and String.prototype.toUpperCase() to capitalize the first letter of the string.
  • Use Array.prototype.join('') to combine the capitalized first with the ...rest of the characters.
  • Omit the lowerRest argument to keep the rest of the string intact, or set it to true to convert to lowercase.
const capitalize = ([first, ...rest], lowerRest = false) =>
  first.toUpperCase() +
  (lowerRest ? rest.join('').toLowerCase() : rest.join(''));
capitalize('fooBar'); // 'FooBar'
capitalize('fooBar', true); // 'Foobar'

title: capitalizeEveryWord

Capitalizes the first letter of every word in a string.

  • Use String.prototype.replace() to match the first character of each word and String.prototype.toUpperCase() to capitalize it.
const capitalizeEveryWord = str =>
  str.replace(/\b[a-z]/g, char => char.toUpperCase());
capitalizeEveryWord('hello world!'); // 'Hello World!'

title: cartesianProduct

Calculates the cartesian product of two arrays.

  • Use Array.prototype.reduce(), Array.prototype.map() and the spread operator (...) to generate all possible element pairs from the two arrays.
const cartesianProduct = (a, b) =>
  a.reduce((p, x) => [...p, ...b.map(y => [x, y])], []);
cartesianProduct(['x', 'y'], [1, 2]);
// [['x', 1], ['x', 2], ['y', 1], ['y', 2]]

title: castArray

Casts the provided value as an array if it's not one.

  • Use Array.prototype.isArray() to determine if val is an array and return it as-is or encapsulated in an array accordingly.
const castArray = val => (Array.isArray(val) ? val : [val]);
castArray('foo'); // ['foo']
castArray([1]); // [1]

title: celsiusToFahrenheit unlisted: true

Converts Celsius to Fahrenheit.

  • Follow the conversion formula F = 1.8 * C + 32.
const celsiusToFahrenheit = degrees => 1.8 * degrees + 32;
celsiusToFahrenheit(33); // 91.4

title: chainAsync

Chains asynchronous functions.

  • Loop through an array of functions containing asynchronous events, calling next when each asynchronous event has completed.
const chainAsync = fns => {
  let curr = 0;
  const last = fns[fns.length - 1];
  const next = () => {
    const fn = fns[curr++];
    fn === last ? fn() : fn(next);
  };
  next();
};
chainAsync([
  next => {
    console.log('0 seconds');
    setTimeout(next, 1000);
  },
  next => {
    console.log('1 second');
    setTimeout(next, 1000);
  },
  () => {
    console.log('2 second');
  }
]);

title: changeLightness

Changes the lightness value of an hsl() color string.

  • Use String.prototype.match() to get an array of 3 strings with the numeric values.
  • Use Array.prototype.map() in combination with Number to convert them into an array of numeric values.
  • Make sure the lightness is within the valid range (between 0 and 100), using Math.max() and Math.min().
  • Use a template literal to create a new hsl() string with the updated value.
const changeLightness = (delta, hslStr) => {
  const [hue, saturation, lightness] = hslStr.match(/\d+/g).map(Number);

  const newLightness = Math.max(
    0,
    Math.min(100, lightness + parseFloat(delta))
  );

  return `hsl(${hue}, ${saturation}%, ${newLightness}%)`;
};
changeLightness(10, 'hsl(330, 50%, 50%)'); // 'hsl(330, 50%, 60%)'
changeLightness(-10, 'hsl(330, 50%, 50%)'); // 'hsl(330, 50%, 40%)'

title: checkProp

Creates a function that will invoke a predicate function for the specified property on a given object.

  • Return a curried function, that will invoke predicate for the specified prop on obj and return a boolean.
const checkProp = (predicate, prop) => obj => !!predicate(obj[prop]);
const lengthIs4 = checkProp(l => l === 4, 'length');
lengthIs4([]); // false
lengthIs4([1, 2, 3, 4]); // true
lengthIs4(new Set([1, 2, 3, 4])); // false (Set uses Size, not length)

const session = { user: {} };
const validUserSession = checkProp(u => u.active && !u.disabled, 'user');

validUserSession(session); // false

session.user.active = true;
validUserSession(session); // true

const noLength = checkProp(l => l === undefined, 'length');
noLength([]); // false
noLength({}); // true
noLength(new Set()); // true

title: chunk

Chunks an array into smaller arrays of a specified size.

  • Use Array.from() to create a new array, that fits the number of chunks that will be produced.
  • Use Array.prototype.slice() to map each element of the new array to a chunk the length of size.
  • If the original array can't be split evenly, the final chunk will contain the remaining elements.
const chunk = (arr, size) =>
  Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
    arr.slice(i * size, i * size + size)
  );
chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]]

title: chunkIntoN

Chunks an array into n smaller arrays.

  • Use Math.ceil() and Array.prototype.length to get the size of each chunk.
  • Use Array.from() to create a new array of size n.
  • Use Array.prototype.slice() to map each element of the new array to a chunk the length of size.
  • If the original array can't be split evenly, the final chunk will contain the remaining elements.
const chunkIntoN = (arr, n) => {
  const size = Math.ceil(arr.length / n);
  return Array.from({ length: n }, (v, i) =>
    arr.slice(i * size, i * size + size)
  );
}
chunkIntoN([1, 2, 3, 4, 5, 6, 7], 4); // [[1, 2], [3, 4], [5, 6], [7]]

title: chunkify

Chunks an iterable into smaller arrays of a specified size.

  • Use a for...of loop over the given iterable, using Array.prototype.push() to add each new value to the current chunk.
  • Use Array.prototype.length to check if the current chunk is of the desired size and yield the value if it is.
  • Finally, use Array.prototype.length to check the final chunk and yield it if it's non-empty.
const chunkify = function* (itr, size) {
  let chunk = [];
  for (const v of itr) {
    chunk.push(v);
    if (chunk.length === size) {
      yield chunk;
      chunk = [];
    }
  }
  if (chunk.length) yield chunk;
};
const x = new Set([1, 2, 1, 3, 4, 1, 2, 5]);
[...chunkify(x, 2)]; // [[1, 2], [3, 4], [5]]

title: clampNumber

Clamps num within the inclusive range specified by the boundary values a and b.

  • If num falls within the range, return num.
  • Otherwise, return the nearest number in the range.
const clampNumber = (num, a, b) =>
  Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b));
clampNumber(2, 3, 5); // 3
clampNumber(1, -1, -5); // -1

title: cloneRegExp

Clones a regular expression.

  • Use new RegExp(), RegExp.prototype.source and RegExp.prototype.flags to clone the given regular expression.
const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags);
const regExp = /lorem ipsum/gi;
const regExp2 = cloneRegExp(regExp); // regExp !== regExp2

title: coalesce

Returns the first defined, non-null argument.

  • Use Array.prototype.find() and Array.prototype.includes() to find the first value that is not equal to undefined or null.
const coalesce = (...args) => args.find(v => ![undefined, null].includes(v));
coalesce(null, undefined, '', NaN, 'Waldo'); // ''

title: coalesceFactory

Customizes a coalesce function that returns the first argument which is true based on the given validator.

  • Use Array.prototype.find() to return the first argument that returns true from the provided argument validation function, valid.
const coalesceFactory = valid => (...args) => args.find(valid);
const customCoalesce = coalesceFactory(
  v => ![null, undefined, '', NaN].includes(v)
);
customCoalesce(undefined, null, NaN, '', 'Waldo'); // 'Waldo'

title: collectInto

Changes a function that accepts an array into a variadic function.

  • Given a function, return a closure that collects all inputs into an array-accepting function.
const collectInto = fn => (...args) => fn(args);
const Pall = collectInto(Promise.all.bind(Promise));
let p1 = Promise.resolve(1);
let p2 = Promise.resolve(2);
let p3 = new Promise(resolve => setTimeout(resolve, 2000, 3));
Pall(p1, p2, p3).then(console.log); // [1, 2, 3] (after about 2 seconds)

title: colorize

Adds special characters to text to print in color in the console (combined with console.log()).

  • Use template literals and special characters to add the appropriate color code to the string output.
  • For background colors, add a special character that resets the background color at the end of the string.
const colorize = (...args) => ({
  black: `\x1b[30m${args.join(' ')}`,
  red: `\x1b[31m${args.join(' ')}`,
  green: `\x1b[32m${args.join(' ')}`,
  yellow: `\x1b[33m${args.join(' ')}`,
  blue: `\x1b[34m${args.join(' ')}`,
  magenta: `\x1b[35m${args.join(' ')}`,
  cyan: `\x1b[36m${args.join(' ')}`,
  white: `\x1b[37m${args.join(' ')}`,
  bgBlack: `\x1b[40m${args.join(' ')}\x1b[0m`,
  bgRed: `\x1b[41m${args.join(' ')}\x1b[0m`,
  bgGreen: `\x1b[42m${args.join(' ')}\x1b[0m`,
  bgYellow: `\x1b[43m${args.join(' ')}\x1b[0m`,
  bgBlue: `\x1b[44m${args.join(' ')}\x1b[0m`,
  bgMagenta: `\x1b[45m${args.join(' ')}\x1b[0m`,
  bgCyan: `\x1b[46m${args.join(' ')}\x1b[0m`,
  bgWhite: `\x1b[47m${args.join(' ')}\x1b[0m`
});
console.log(colorize('foo').red); // 'foo' (red letters)
console.log(colorize('foo', 'bar').bgBlue); // 'foo bar' (blue background)
console.log(colorize(colorize('foo').yellow, colorize('foo').green).bgWhite);
// 'foo bar' (first word in yellow letters, second word in green letters, white background for both)

title: combine

Combines two arrays of objects, using the specified key to match objects.

  • Use Array.prototype.reduce() with an object accumulator to combine all objects in both arrays based on the given prop.
  • Use Object.values() to convert the resulting object to an array and return it.
const combine = (a, b, prop) =>
  Object.values(
    [...a, ...b].reduce((acc, v) => {
      if (v[prop])
        acc[v[prop]] = acc[v[prop]]
          ? { ...acc[v[prop]], ...v }
          : { ...v };
      return acc;
    }, {})
  );
const x = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Maria' }
];
const y = [
  { id: 1, age: 28 },
  { id: 3, age: 26 },
  { age: 3}
];
combine(x, y, 'id');
// [
//  { id: 1, name: 'John', age: 28 },
//  { id: 2, name: 'Maria' },
//  { id: 3, age: 26 }
// ]

title: compact

Removes falsy values from an array.

  • Use Array.prototype.filter() to filter out falsy values (false, null, 0, "", undefined, and NaN).
const compact = arr => arr.filter(Boolean);
compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]); 
// [ 1, 2, 3, 'a', 's', 34 ]

title: compactObject

Deeply removes all falsy values from an object or array.

  • Use recursion.
  • Initialize the iterable data, using Array.isArray(), Array.prototype.filter() and Boolean for arrays in order to avoid sparse arrays.
  • Use Object.keys() and Array.prototype.reduce() to iterate over each key with an appropriate initial value.
  • Use Boolean to determine the truthiness of each key's value and add it to the accumulator if it's truthy.
  • Use typeof to determine if a given value is an object and call the function again to deeply compact it.
const compactObject = val => {
  const data = Array.isArray(val) ? val.filter(Boolean) : val;
  return Object.keys(data).reduce(
    (acc, key) => {
      const value = data[key];
      if (Boolean(value))
        acc[key] = typeof value === 'object' ? compactObject(value) : value;
      return acc;
    },
    Array.isArray(val) ? [] : {}
  );
};
const obj = {
  a: null,
  b: false,
  c: true,
  d: 0,
  e: 1,
  f: '',
  g: 'a',
  h: [null, false, '', true, 1, 'a'],
  i: { j: 0, k: false, l: 'a' }
};
compactObject(obj);
// { c: true, e: 1, g: 'a', h: [ true, 1, 'a' ], i: { l: 'a' } }

title: compactWhitespace

Compacts whitespaces in a string.

  • Use String.prototype.replace() with a regular expression to replace all occurrences of 2 or more whitespace characters with a single space.
const compactWhitespace = str => str.replace(/\s{2,}/g, ' ');
compactWhitespace('Lorem    Ipsum'); // 'Lorem Ipsum'
compactWhitespace('Lorem \n Ipsum'); // 'Lorem Ipsum'

title: complement

Returns a function that is the logical complement of the given function, fn.

  • Use the logical not (!) operator on the result of calling fn with any supplied args.
const complement = fn => (...args) => !fn(...args);
const isEven = num => num % 2 === 0;
const isOdd = complement(isEven);
isOdd(2); // false
isOdd(3); // true

title: compose

Performs right-to-left function composition.

  • Use Array.prototype.reduce() to perform right-to-left function composition.
  • The last (rightmost) function can accept one or more arguments; the remaining functions must be unary.
const compose = (...fns) =>
  fns.reduce((f, g) => (...args) => f(g(...args)));
const add5 = x => x + 5;
const multiply = (x, y) => x * y;
const multiplyAndAdd5 = compose(
  add5,
  multiply
);
multiplyAndAdd5(5, 2); // 15

title: composeRight

Performs left-to-right function composition.

  • Use Array.prototype.reduce() to perform left-to-right function composition.
  • The first (leftmost) function can accept one or more arguments; the remaining functions must be unary.
const composeRight = (...fns) =>
  fns.reduce((f, g) => (...args) => g(f(...args)));
const add = (x, y) => x + y;
const square = x => x * x;
const addAndSquare = composeRight(add, square);
addAndSquare(1, 2); // 9

title: containsWhitespace

Checks if the given string contains any whitespace characters.

  • Use RegExp.prototype.test() with an appropriate regular expression to check if the given string contains any whitespace characters.
const containsWhitespace = str => /\s/.test(str);
containsWhitespace('lorem'); // false
containsWhitespace('lorem ipsum'); // true

title: converge

Accepts a converging function and a list of branching functions and returns a function that applies each branching function to the arguments and the results of the branching functions are passed as arguments to the converging function.

  • Use Array.prototype.map() and Function.prototype.apply() to apply each function to the given arguments.
  • Use the spread operator (...) to call converger with the results of all other functions.
const converge = (converger, fns) => (...args) =>
  converger(...fns.map(fn => fn.apply(null, args)));
const average = converge((a, b) => a / b, [
  arr => arr.reduce((a, v) => a + v, 0),
  arr => arr.length
]);
average([1, 2, 3, 4, 5, 6, 7]); // 4

title: copySign

Returns the absolute value of the first number, but the sign of the second.

  • Use Math.sign() to check if the two numbers have the same sign.
  • Return x if they do, -x otherwise.
const copySign = (x, y) => Math.sign(x) === Math.sign(y) ? x : -x;
copySign(2, 3); // 2
copySign(2, -3); // -2
copySign(-2, 3); // 2
copySign(-2, -3); // -2

title: copyToClipboard

Copies a string to the clipboard. Only works as a result of user action (i.e. inside a click event listener).

  • Create a new <textarea> element, fill it with the supplied data and add it to the HTML document.
  • Use Selection.getRangeAt()to store the selected range (if any).
  • Use Document.execCommand('copy') to copy to the clipboard.
  • Remove the <textarea> element from the HTML document.
  • Finally, use Selection().addRange() to recover the original selected range (if any).
  • Note: You can use the new asynchronous Clipboard API to implement the same functionality. It's experimental but should be used in the future instead of this snippet. Find out more about it here.
const copyToClipboard = str => {
  const el = document.createElement('textarea');
  el.value = str;
  el.setAttribute('readonly', '');
  el.style.position = 'absolute';
  el.style.left = '-9999px';
  document.body.appendChild(el);
  const selected =
    document.getSelection().rangeCount > 0
      ? document.getSelection().getRangeAt(0)
      : false;
  el.select();
  document.execCommand('copy');
  document.body.removeChild(el);
  if (selected) {
    document.getSelection().removeAllRanges();
    document.getSelection().addRange(selected);
  }
};
copyToClipboard('Lorem ipsum'); // 'Lorem ipsum' copied to clipboard.

title: countBy

Groups the elements of an array based on the given function and returns the count of elements in each group.

  • Use Array.prototype.map() to map the values of an array to a function or property name.
  • Use Array.prototype.reduce() to create an object, where the keys are produced from the mapped results.
const countBy = (arr, fn) =>
  arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => {
    acc[val] = (acc[val] || 0) + 1;
    return acc;
  }, {});
countBy([6.1, 4.2, 6.3], Math.floor); // {4: 1, 6: 2}
countBy(['one', 'two', 'three'], 'length'); // {3: 2, 5: 1}
countBy([{ count: 5 }, { count: 10 }, { count: 5 }], x => x.count)
// {5: 2, 10: 1}

title: countOccurrences

Counts the occurrences of a value in an array.

  • Use Array.prototype.reduce() to increment a counter each time the specific value is encountered inside the array.
const countOccurrences = (arr, val) =>
  arr.reduce((a, v) => (v === val ? a + 1 : a), 0);
countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3

title: countSubstrings

Counts the occurrences of a substring in a given string.

  • Use Array.prototype.indexOf() to look for searchValue in str.
  • Increment a counter if the value is found and update the index, i.
  • Use a while loop that will return as soon as the value returned from Array.prototype.indexOf() is -1.
const countSubstrings = (str, searchValue) => {
  let count = 0,
    i = 0;
  while (true) {
    const r = str.indexOf(searchValue, i);
    if (r !== -1) [count, i] = [count + 1, r + 1];
    else return count;
  }
};
countSubstrings('tiktok tok tok tik tok tik', 'tik'); // 3
countSubstrings('tutut tut tut', 'tut'); // 4

title: countWeekDaysBetween

Counts the weekdays between two dates.

  • Use Array.from() to construct an array with length equal to the number of days between startDate and endDate.
  • Use Array.prototype.reduce() to iterate over the array, checking if each date is a weekday and incrementing count.
  • Update startDate with the next day each loop using Date.prototype.getDate() and Date.prototype.setDate() to advance it by one day.
  • NOTE: Does not take official holidays into account.
const countWeekDaysBetween = (startDate, endDate) =>
  Array
    .from({ length: (endDate - startDate) / (1000 * 3600 * 24) })
    .reduce(count => {
      if (startDate.getDay() % 6 !== 0) count++;
      startDate = new Date(startDate.setDate(startDate.getDate() + 1));
      return count;
    }, 0);
countWeekDaysBetween(new Date('Oct 05, 2020'), new Date('Oct 06, 2020')); // 1
countWeekDaysBetween(new Date('Oct 05, 2020'), new Date('Oct 14, 2020')); // 7

title: counter

Creates a counter with the specified range, step and duration for the specified selector.

  • Check if step has the proper sign and change it accordingly.
  • Use setInterval() in combination with Math.abs() and Math.floor() to calculate the time between each new text draw.
  • Use Document.querySelector(), Element.innerHTML to update the value of the selected element.
  • Omit the fourth argument, step, to use a default step of 1.
  • Omit the fifth argument, duration, to use a default duration of 2000ms.
const counter = (selector, start, end, step = 1, duration = 2000) => {
  let current = start,
    _step = (end - start) * step < 0 ? -step : step,
    timer = setInterval(() => {
      current += _step;
      document.querySelector(selector).innerHTML = current;
      if (current >= end) document.querySelector(selector).innerHTML = end;
      if (current >= end) clearInterval(timer);
    }, Math.abs(Math.floor(duration / (end - start))));
  return timer;
};
counter('#my-id', 1, 1000, 5, 2000);
// Creates a 2-second timer for the element with id="my-id"

title: createDirIfNotExists

Creates a directory, if it does not exist.

  • Use fs.existsSync() to check if the directory exists, fs.mkdirSync() to create it.
const fs = require('fs');

const createDirIfNotExists = dir => (!fs.existsSync(dir) ? fs.mkdirSync(dir) : undefined);
createDirIfNotExists('test');
// creates the directory 'test', if it doesn't exist

title: createElement

Creates an element from a string (without appending it to the document). If the given string contains multiple elements, only the first one will be returned.

  • Use Document.createElement() to create a new element.
  • Use Element.innerHTML to set its inner HTML to the string supplied as the argument.
  • Use ParentNode.firstElementChild to return the element version of the string.
const createElement = str => {
  const el = document.createElement('div');
  el.innerHTML = str;
  return el.firstElementChild;
};
const el = createElement(
  `<div class="container">
    <p>Hello!</p>
  </div>`
);
console.log(el.className); // 'container'

title: createEventHub

Creates a pub/sub (publish–subscribe) event hub with emit, on, and off methods.

  • Use Object.create(null) to create an empty hub object that does not inherit properties from Object.prototype.
  • For emit, resolve the array of handlers based on the event argument and then run each one with Array.prototype.forEach() by passing in the data as an argument.
  • For on, create an array for the event if it does not yet exist, then use Array.prototype.push() to add the handler
  • to the array.
  • For off, use Array.prototype.findIndex() to find the index of the handler in the event array and remove it using Array.prototype.splice().
const createEventHub = () => ({
  hub: Object.create(null),
  emit(event, data) {
    (this.hub[event] || []).forEach(handler => handler(data));
  },
  on(event, handler) {
    if (!this.hub[event]) this.hub[event] = [];
    this.hub[event].push(handler);
  },
  off(event, handler) {
    const i = (this.hub[event] || []).findIndex(h => h === handler);
    if (i > -1) this.hub[event].splice(i, 1);
    if (this.hub[event].length === 0) delete this.hub[event];
  }
});
const handler = data => console.log(data);
const hub = createEventHub();
let increment = 0;

// Subscribe: listen for different types of events
hub.on('message', handler);
hub.on('message', () => console.log('Message event fired'));
hub.on('increment', () => increment++);

// Publish: emit events to invoke all handlers subscribed to them, passing the data to them as an argument
hub.emit('message', 'hello world'); // logs 'hello world' and 'Message event fired'
hub.emit('message', { hello: 'world' }); // logs the object and 'Message event fired'
hub.emit('increment'); // `increment` variable is now 1

// Unsubscribe: stop a specific handler from listening to the 'message' event
hub.off('message', handler);

title: currentURL

Returns the current URL.

  • Use Window.location.href to get the current URL.
const currentURL = () => window.location.href;
currentURL(); // 'https://www.google.com/'

title: curry

Curries a function.

  • Use recursion.
  • If the number of provided arguments (args) is sufficient, call the passed function fn.
  • Otherwise, use Function.prototype.bind() to return a curried function fn that expects the rest of the arguments.
  • If you want to curry a function that accepts a variable number of arguments (a variadic function, e.g. Math.min()), you can optionally pass the number of arguments to the second parameter arity.
const curry = (fn, arity = fn.length, ...args) =>
  arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args);
curry(Math.pow)(2)(10); // 1024
curry(Math.min, 3)(10)(50)(2); // 2

title: cycleGenerator

Creates a generator, looping over the given array indefinitely.

  • Use a non-terminating while loop, that will yield a value every time Generator.prototype.next() is called.
  • Use the module operator (%) with Array.prototype.length to get the next value's index and increment the counter after each yield statement.
const cycleGenerator = function* (arr) {
  let i = 0;
  while (true) {
    yield arr[i % arr.length];
    i++;
  }
};
const binaryCycle = cycleGenerator([0, 1]);
binaryCycle.next(); // { value: 0, done: false }
binaryCycle.next(); // { value: 1, done: false }
binaryCycle.next(); // { value: 0, done: false }
binaryCycle.next(); // { value: 1, done: false }

title: dateRangeGenerator

Creates a generator, that generates all dates in the given range using the given step.

  • Use a while loop to iterate from start to end, using yield to return each date in the range, using the Date constructor.
  • Use Date.prototype.getDate() and Date.prototype.setDate() to increment by step days after returning each subsequent value.
  • Omit the third argument, step, to use a default value of 1.
const dateRangeGenerator = function* (start, end, step = 1) {
  let d = start;
  while (d < end) {
    yield new Date(d);
    d.setDate(d.getDate() + step);
  }
};
[...dateRangeGenerator(new Date('2021-06-01'), new Date('2021-06-04'))];
// [ 2021-06-01, 2021-06-02, 2021-06-03 ]

title: dayName

Gets the name of the weekday from a Date object.

  • Use Date.prototype.toLocaleDateString() with the { weekday: 'long' } option to retrieve the weekday.
  • Use the optional second argument to get a language-specific name or omit it to use the default locale.
const dayName = (date, locale) =>
  date.toLocaleDateString(locale, { weekday: 'long' });
dayName(new Date()); // 'Saturday'
dayName(new Date('09/23/2020'), 'de-DE'); // 'Samstag'

title: dayOfYear

Gets the day of the year (number in the range 1-366) from a Date object.

  • Use new Date() and Date.prototype.getFullYear() to get the first day of the year as a Date object.
  • Subtract the first day of the year from date and divide with the milliseconds in each day to get the result.
  • Use Math.floor() to appropriately round the resulting day count to an integer.
const dayOfYear = date =>
  Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);
dayOfYear(new Date()); // 272

title: daysAgo

Calculates the date of n days ago from today as a string representation.

  • Use new Date() to get the current date, Math.abs() and Date.prototype.getDate() to update the date accordingly and set to the result using Date.prototype.setDate().
  • Use Date.prototype.toISOString() to return a string in yyyy-mm-dd format.
const daysAgo = n => {
  let d = new Date();
  d.setDate(d.getDate() - Math.abs(n));
  return d.toISOString().split('T')[0];
};
daysAgo(20); // 2020-09-16 (if current date is 2020-10-06)

title: daysFromNow

Calculates the date of n days from today as a string representation.

  • Use new Date() to get the current date, Math.abs() and Date.prototype.getDate() to update the date accordingly and set to the result using Date.prototype.setDate().
  • Use Date.prototype.toISOString() to return a string in yyyy-mm-dd format.
const daysFromNow = n => {
  let d = new Date();
  d.setDate(d.getDate() + Math.abs(n));
  return d.toISOString().split('T')[0];
};
daysFromNow(5); // 2020-10-13 (if current date is 2020-10-08)

title: daysInMonth

Gets the number of days in the given month of the specified year.

  • Use the new Date() constructor to create a date from the given year and month.
  • Set the days parameter to 0 to get the last day of the previous month, as months are zero-indexed.
  • Use Date.prototype.getDate() to return the number of days in the given month.
const daysInMonth = (year, month) => new Date(year, month, 0).getDate();
daysInMonth(2020, 12)); // 31
daysInMonth(2024, 2)); // 29

title: debounce

Creates a debounced function that delays invoking the provided function until at least ms milliseconds have elapsed since its last invocation.

  • Each time the debounced function is invoked, clear the current pending timeout with clearTimeout(). Use setTimeout() to create a new timeout that delays invoking the function until at least ms milliseconds have elapsed.
  • Use Function.prototype.apply() to apply the this context to the function and provide the necessary arguments.
  • Omit the second argument, ms, to set the timeout at a default of 0 ms.
const debounce = (fn, ms = 0) => {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn.apply(this, args), ms);
  };
};
window.addEventListener(
  'resize',
  debounce(() => {
    console.log(window.innerWidth);
    console.log(window.innerHeight);
  }, 250)
); // Will log the window dimensions at most every 250ms

title: debouncePromise

Creates a debounced function that returns a promise, but delays invoking the provided function until at least ms milliseconds have elapsed since the last time it was invoked. All promises returned during this time will return the same data.

  • Each time the debounced function is invoked, clear the current pending timeout with clearTimeout() and use setTimeout() to create a new timeout that delays invoking the function until at least ms milliseconds has elapsed.
  • Use Function.prototype.apply() to apply the this context to the function and provide the necessary arguments.
  • Create a new Promise and add its resolve and reject callbacks to the pending promises stack.
  • When setTimeout is called, copy the current stack (as it can change between the provided function call and its resolution), clear it and call the provided function.
  • When the provided function resolves/rejects, resolve/reject all promises in the stack (copied when the function was called) with the returned data.
  • Omit the second argument, ms, to set the timeout at a default of 0 ms.
const debouncePromise = (fn, ms = 0) => {
  let timeoutId;
  const pending = [];
  return (...args) =>
    new Promise((res, rej) => {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => {
        const currentPending = [...pending];
        pending.length = 0;
        Promise.resolve(fn.apply(this, args)).then(
          data => {
            currentPending.forEach(({ resolve }) => resolve(data));
          },
          error => {
            currentPending.forEach(({ reject }) => reject(error));
          }
        );
      }, ms);
      pending.push({ resolve: res, reject: rej });
    });
};
const fn = arg => new Promise(resolve => {
  setTimeout(resolve, 1000, ['resolved', arg]);
});
const debounced = debouncePromise(fn, 200);
debounced('foo').then(console.log);
debounced('bar').then(console.log);
// Will log ['resolved', 'bar'] both times

title: decapitalize

Decapitalizes the first letter of a string.

  • Use array destructuring and String.prototype.toLowerCase() to decapitalize first letter, ...rest to get array of characters after first letter and then Array.prototype.join('') to make it a string again.
  • Omit the upperRest argument to keep the rest of the string intact, or set it to true to convert to uppercase.
const decapitalize = ([first, ...rest], upperRest = false) =>
  first.toLowerCase() +
  (upperRest ? rest.join('').toUpperCase() : rest.join(''));
decapitalize('FooBar'); // 'fooBar'
decapitalize('FooBar', true); // 'fOOBAR'

title: deepClone

Creates a deep clone of an object. Clones primitives, arrays and objects, excluding class instances.

  • Use recursion.
  • Check if the passed object is null and, if so, return null.
  • Use Object.assign() and an empty object ({}) to create a shallow clone of the original.
  • Use Object.keys() and Array.prototype.forEach() to determine which key-value pairs need to be deep cloned.
  • If the object is an Array, set the clone's length to that of the original and use Array.from(clone) to create a clone.
const deepClone = obj => {
  if (obj === null) return null;
  let clone = Object.assign({}, obj);
  Object.keys(clone).forEach(
    key =>
      (clone[key] =
        typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
  );
  if (Array.isArray(obj)) {
    clone.length = obj.length;
    return Array.from(clone);
  }
  return clone;
};
const a = { foo: 'bar', obj: { a: 1, b: 2 } };
const b = deepClone(a); // a !== b, a.obj !== b.obj

title: deepFlatten

Deep flattens an array.

  • Use recursion.
  • Use Array.prototype.concat() with an empty array ([]) and the spread operator (...) to flatten an array.
  • Recursively flatten each element that is an array.
const deepFlatten = arr =>
  [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));
deepFlatten([1, [2], [[3], 4], 5]); // [1, 2, 3, 4, 5]

title: deepFreeze

Deep freezes an object.

  • Use Object.keys() to get all the properties of the passed object, Array.prototype.forEach() to iterate over them.
  • Call Object.freeze(obj) recursively on all properties, applying deepFreeze() as necessary.
  • Finally, use Object.freeze() to freeze the given object.
const deepFreeze = obj => {
  Object.keys(obj).forEach(prop => {
    if (typeof obj[prop] === 'object') deepFreeze(obj[prop]);
  });
  return Object.freeze(obj);
};
'use strict';

const val = deepFreeze([1, [2, 3]]);

val[0] = 3; // not allowed
val[1][0] = 4; // not allowed as well

title: deepGet

Gets the target value in a nested JSON object, based on the keys array.

  • Compare the keys you want in the nested JSON object as an Array.
  • Use Array.prototype.reduce() to get the values in the nested JSON object one by one.
  • If the key exists in the object, return the target value, otherwise return null.
const deepGet = (obj, keys) =>
  keys.reduce(
    (xs, x) => (xs && xs[x] !== null && xs[x] !== undefined ? xs[x] : null),
    obj
  );
let index = 2;
const data = {
  foo: {
    foz: [1, 2, 3],
    bar: {
      baz: ['a', 'b', 'c']
    }
  }
};
deepGet(data, ['foo', 'foz', index]); // get 3
deepGet(data, ['foo', 'bar', 'baz', 8, 'foz']); // null

title: deepMapKeys

Deep maps an object's keys.

  • Creates an object with the same values as the provided object and keys generated by running the provided function for each key.
  • Use Object.keys(obj) to iterate over the object's keys.
  • Use Array.prototype.reduce() to create a new object with the same values and mapped keys using fn.
const deepMapKeys = (obj, fn) =>
  Array.isArray(obj)
    ? obj.map(val => deepMapKeys(val, fn))
    : typeof obj === 'object'
    ? Object.keys(obj).reduce((acc, current) => {
        const key = fn(current);
        const val = obj[current];
        acc[key] =
          val !== null && typeof val === 'object' ? deepMapKeys(val, fn) : val;
        return acc;
      }, {})
    : obj;
const obj = {
  foo: '1',
  nested: {
    child: {
      withArray: [
        {
          grandChild: ['hello']
        }
      ]
    }
  }
};
const upperKeysObj = deepMapKeys(obj, key => key.toUpperCase());
/*
{
  "FOO":"1",
  "NESTED":{
    "CHILD":{
      "WITHARRAY":[
        {
          "GRANDCHILD":[ 'hello' ]
        }
      ]
    }
  }
}
*/

title: deepMerge

Deeply merges two objects, using a function to handle keys present in both.

  • Use Object.keys() to get the keys of both objects, create a Set from them and use the spread operator (...) to create an array of all the unique keys.
  • Use Array.prototype.reduce() to add each unique key to the object, using fn to combine the values of the two given objects.
const deepMerge = (a, b, fn) =>
  [...new Set([...Object.keys(a), ...Object.keys(b)])].reduce(
    (acc, key) => ({ ...acc, [key]: fn(key, a[key], b[key]) }),
    {}
  );
deepMerge(
  { a: true, b: { c: [1, 2, 3] } },
  { a: false, b: { d: [1, 2, 3] } },
  (key, a, b) => (key === 'a' ? a && b : Object.assign({}, a, b))
);
// { a: false, b: { c: [ 1, 2, 3 ], d: [ 1, 2, 3 ] } }

title: defaults

Assigns default values for all properties in an object that are undefined.

  • Use Object.assign() to create a new empty object and copy the original one to maintain key order.
  • Use Array.prototype.reverse() and the spread operator (...) to combine the default values from left to right.
  • Finally, use obj again to overwrite properties that originally had a value.
const defaults = (obj, ...defs) =>
  Object.assign({}, obj, ...defs.reverse(), obj);
defaults({ a: 1 }, { b: 2 }, { b: 6 }, { a: 3 }); // { a: 1, b: 2 }

title: defer

Defers invoking a function until the current call stack has cleared.

  • Use setTimeout() with a timeout of 1 ms to add a new event to the event queue and allow the rendering engine to complete its work.
  • Use the spread (...) operator to supply the function with an arbitrary number of arguments.
const defer = (fn, ...args) => setTimeout(fn, 1, ...args);
// Example A:
defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a'

// Example B:
document.querySelector('#someElement').innerHTML = 'Hello';
longRunningFunction();
// Browser will not update the HTML until this has finished
defer(longRunningFunction);
// Browser will update the HTML then run the function

title: degreesToRads

Converts an angle from degrees to radians.

  • Use Math.PI and the degree to radian formula to convert the angle from degrees to radians.
const degreesToRads = deg => (deg * Math.PI) / 180.0;
degreesToRads(90.0); // ~1.5708

title: delay

Invokes the provided function after ms milliseconds.

  • Use setTimeout() to delay execution of fn.
  • Use the spread (...) operator to supply the function with an arbitrary number of arguments.
const delay = (fn, ms, ...args) => setTimeout(fn, ms, ...args);
delay(
  function(text) {
    console.log(text);
  },
  1000,
  'later'
); // Logs 'later' after one second.

title: detectDeviceType

Detects whether the page is being viewed on a mobile device or a desktop.

  • Use a regular expression to test the navigator.userAgent property to figure out if the device is a mobile device or a desktop.
const detectDeviceType = () =>
  /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
    navigator.userAgent
  )
    ? 'Mobile'
    : 'Desktop';
detectDeviceType(); // 'Mobile' or 'Desktop'

title: detectLanguage

Detects the preferred language of the current user.

  • Use NavigationLanguage.language or the first NavigationLanguage.languages if available, otherwise return defaultLang.
  • Omit the second argument, defaultLang, to use 'en-US' as the default language code.
const detectLanguage = (defaultLang = 'en-US') => 
  navigator.language ||
  (Array.isArray(navigator.languages) && navigator.languages[0]) ||
  defaultLang;
detectLanguage(); // 'nl-NL'

title: difference

Calculates the difference between two arrays, without filtering duplicate values.

  • Create a Set from b to get the unique values in b.
  • Use Array.prototype.filter() on a to only keep values not contained in b, using Set.prototype.has().
const difference = (a, b) => {
  const s = new Set(b);
  return a.filter(x => !s.has(x));
};
difference([1, 2, 3, 3], [1, 2, 4]); // [3, 3]

title: differenceBy

Returns the difference between two arrays, after applying the provided function to each array element of both.

  • Create a Set by applying fn to each element in b.
  • Use Array.prototype.map() to apply fn to each element in a.
  • Use Array.prototype.filter() in combination with fn on a to only keep values not contained in b, using Set.prototype.has().
const differenceBy = (a, b, fn) => {
  const s = new Set(b.map(fn));
  return a.map(fn).filter(el => !s.has(el));
};
differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [1]
differenceBy([{ x: 2 }, { x: 1 }], [{ x: 1 }], v => v.x); // [2]

title: differenceWith

Filters out all values from an array for which the comparator function does not return true.

  • Use Array.prototype.filter() and Array.prototype.findIndex() to find the appropriate values.
  • Omit the last argument, comp, to use a default strict equality comparator.
const differenceWith = (arr, val, comp = (a, b) => a === b) =>
  arr.filter(a => val.findIndex(b => comp(a, b)) === -1);
differenceWith(
  [1, 1.2, 1.5, 3, 0],
  [1.9, 3, 0],
  (a, b) => Math.round(a) === Math.round(b)
); // [1, 1.2]
differenceWith([1, 1.2, 1.3], [1, 1.3, 1.5]); // [1.2]

title: dig

Gets the target value in a nested JSON object, based on the given key.

  • Use the in operator to check if target exists in obj.
  • If found, return the value of obj[target].
  • Otherwise use Object.values(obj) and Array.prototype.reduce() to recursively call dig on each nested object until the first matching key/value pair is found.
const dig = (obj, target) =>
  target in obj
    ? obj[target]
    : Object.values(obj).reduce((acc, val) => {
        if (acc !== undefined) return acc;
        if (typeof val === 'object') return dig(val, target);
      }, undefined);
const data = {
  level1: {
    level2: {
      level3: 'some data'
    }
  }
};
dig(data, 'level3'); // 'some data'
dig(data, 'level4'); // undefined

title: digitize

Converts a number to an array of digits, removing its sign if necessary.

  • Use Math.abs() to strip the number's sign.
  • Convert the number to a string, using the spread operator (...) to build an array.
  • Use Array.prototype.map() and parseInt() to transform each value to an integer.
const digitize = n => [...`${Math.abs(n)}`].map(i => parseInt(i));
digitize(123); // [1, 2, 3]
digitize(-123); // [1, 2, 3]

title: distance

Calculates the distance between two points.

  • Use Math.hypot() to calculate the Euclidean distance between two points.
const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0);
distance(1, 1, 2, 3); // ~2.2361

title: divmod

Returns an array consisting of the quotient and remainder of the given numbers.

  • Use Math.floor() to get the quotient of the division x / y.
  • Use the modulo operator (%) to get the remainder of the division x / y.
const divmod = (x, y) => [Math.floor(x / y), x % y];
divmod(8, 3); // [2, 2]
divmod(3, 8); // [0, 3]
divmod(5, 5); // [1, 0]

title: drop

Creates a new array with n elements removed from the left.

  • Use Array.prototype.slice() to remove the specified number of elements from the left.
  • Omit the last argument, n, to use a default value of 1.
const drop = (arr, n = 1) => arr.slice(n);
drop([1, 2, 3]); // [2, 3]
drop([1, 2, 3], 2); // [3]
drop([1, 2, 3], 42); // []

title: dropRight

Creates a new array with n elements removed from the right.

  • Use Array.prototype.slice() to remove the specified number of elements from the right.
  • Omit the last argument, n, to use a default value of 1.
const dropRight = (arr, n = 1) => arr.slice(0, -n);
dropRight([1, 2, 3]); // [1, 2]
dropRight([1, 2, 3], 2); // [1]
dropRight([1, 2, 3], 42); // []

title: dropRightWhile

Removes elements from the end of an array until the passed function returns true. Returns the remaining elements in the array.

  • Loop through the array, using Array.prototype.slice() to drop the last element of the array until the value returned from func is true.
  • Return the remaining elements.
const dropRightWhile = (arr, func) => {
  let rightIndex = arr.length;
  while (rightIndex-- && !func(arr[rightIndex]));
  return arr.slice(0, rightIndex + 1);
};
dropRightWhile([1, 2, 3, 4], n => n < 3); // [1, 2]

title: dropWhile

Removes elements in an array until the passed function returns true. Returns the remaining elements in the array.

  • Loop through the array, using Array.prototype.slice() to drop the first element of the array until the value returned from func is true.
  • Return the remaining elements.
const dropWhile = (arr, func) => {
  while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1);
  return arr;
};
dropWhile([1, 2, 3, 4], n => n >= 3); // [3, 4]

title: either

Checks if at least one function returns true for a given set of arguments.

  • Use the logical or (||) operator on the result of calling the two functions with the supplied args.
const either = (f, g) => (...args) => f(...args) || g(...args);
const isEven = num => num % 2 === 0;
const isPositive = num => num > 0;
const isPositiveOrEven = either(isPositive, isEven);
isPositiveOrEven(4); // true
isPositiveOrEven(3); // true

title: elementContains

Checks if the parent element contains the child element.

  • Check that parent is not the same element as child.
  • Use Node.contains() to check if the parent element contains the child element.
const elementContains = (parent, child) =>
  parent !== child && parent.contains(child);
elementContains(
  document.querySelector('head'),
  document.querySelector('title')
);
// true
elementContains(document.querySelector('body'), document.querySelector('body'));
// false

title: elementIsFocused

Checks if the given element is focused.

  • Use Document.activeElement to determine if the given element is focused.
const elementIsFocused = el => (el === document.activeElement);
elementIsFocused(el); // true if the element is focused

title: elementIsVisibleInViewport

Checks if the element specified is visible in the viewport.

  • Use Element.getBoundingClientRect() and the Window.inner(Width|Height) values to determine if a given element is visible in the viewport.
  • Omit the second argument to determine if the element is entirely visible, or specify true to determine if it is partially visible.
const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
  const { top, left, bottom, right } = el.getBoundingClientRect();
  const { innerHeight, innerWidth } = window;
  return partiallyVisible
    ? ((top > 0 && top < innerHeight) ||
        (bottom > 0 && bottom < innerHeight)) &&
        ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
    : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};
// e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10}
elementIsVisibleInViewport(el); // false - (not fully visible)
elementIsVisibleInViewport(el, true); // true - (partially visible)

title: equals

Performs a deep comparison between two values to determine if they are equivalent.

  • Check if the two values are identical.
  • Check if both values are Date objects with the same time, using Date.prototype.getTime().
  • Check if both values are non-object values with an equivalent value (strict comparison).
  • Check if only one value is null or undefined or if their prototypes differ.
  • If none of the above conditions are met, use Object.keys() to check if both values have the same number of keys.
  • Use Array.prototype.every() to check if every key in a exists in b and if they are equivalent by calling equals() recursively.
const equals = (a, b) => {
  if (a === b) return true;

  if (a instanceof Date && b instanceof Date)
    return a.getTime() === b.getTime();

  if (!a || !b || (typeof a !== 'object' && typeof b !== 'object'))
    return a === b;

  if (a.prototype !== b.prototype) return false;

  const keys = Object.keys(a);
  if (keys.length !== Object.keys(b).length) return false;

  return keys.every(k => equals(a[k], b[k]));
};
equals(
  { a: [2, { e: 3 }], b: [4], c: 'foo' },
  { a: [2, { e: 3 }], b: [4], c: 'foo' }
); // true
equals([1, 2, 3], { 0: 1, 1: 2, 2: 3 }); // true

title: escapeHTML

Escapes a string for use in HTML.

  • Use String.prototype.replace() with a regexp that matches the characters that need to be escaped.
  • Use the callback function to replace each character instance with its associated escaped character using a dictionary object.
const escapeHTML = str =>
  str.replace(
    /[&<>'"]/g,
    tag =>
      ({
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        "'": '&#39;',
        '"': '&quot;'
      }[tag] || tag)
  );
escapeHTML('<a href="#">Me & you</a>');
// '&lt;a href=&quot;#&quot;&gt;Me &amp; you&lt;/a&gt;'

title: escapeRegExp

Escapes a string to use in a regular expression.

  • Use String.prototype.replace() to escape special characters.
const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
escapeRegExp('(test)'); // \\(test\\)

title: euclideanDistance

Calculates the distance between two points in any number of dimensions.

  • Use Object.keys() and Array.prototype.map() to map each coordinate to its difference between the two points.
  • Use Math.hypot() to calculate the Euclidean distance between the two points.
const euclideanDistance = (a, b) =>
  Math.hypot(...Object.keys(a).map(k => b[k] - a[k]));
euclideanDistance([1, 1], [2, 3]); // ~2.2361
euclideanDistance([1, 1, 1], [2, 3, 2]); // ~2.4495

title: everyNth

Returns every nth element in an array.

  • Use Array.prototype.filter() to create a new array that contains every nth element of a given array.
const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1);
everyNth([1, 2, 3, 4, 5, 6], 2); // [ 2, 4, 6 ]

title: expandTabs

Convert tabs to spaces, where each tab corresponds to count spaces.

  • Use String.prototype.replace() with a regular expression and String.prototype.repeat() to replace each tab character with count spaces.
const expandTabs = (str, count) => str.replace(/\t/g, ' '.repeat(count));
expandTabs('\t\tlorem', 3); // '      lorem'

title: extendHex

Extends a 3-digit color code to a 6-digit color code.

  • Use Array.prototype.map(), String.prototype.split() and Array.prototype.join() to join the mapped array for converting a 3-digit RGB notated hexadecimal color-code to the 6-digit form.
  • Array.prototype.slice() is used to remove # from string start since it's added once.
const extendHex = shortHex =>
  '#' +
  shortHex
    .slice(shortHex.startsWith('#') ? 1 : 0)
    .split('')
    .map(x => x + x)
    .join('');
extendHex('#03f'); // '#0033ff'
extendHex('05a'); // '#0055aa'

title: factorial

Calculates the factorial of a number.

  • Use recursion.
  • If n is less than or equal to 1, return 1.
  • Otherwise, return the product of n and the factorial of n - 1.
  • Throw a TypeError if n is a negative number.
const factorial = n =>
  n < 0
    ? (() => {
        throw new TypeError('Negative numbers are not allowed!');
      })()
    : n <= 1
    ? 1
    : n * factorial(n - 1);
factorial(6); // 720

title: fahrenheitToCelsius unlisted: true

Converts Fahrenheit to Celsius.

  • Follow the conversion formula C = (F - 32) * 5/9.
const fahrenheitToCelsius = degrees => (degrees - 32) * 5 / 9;
fahrenheitToCelsius(32); // 0

title: fibonacci

Generates an array, containing the Fibonacci sequence, up until the nth term.

  • Use Array.from() to create an empty array of the specific length, initializing the first two values (0 and 1).
  • Use Array.prototype.reduce() and Array.prototype.concat() to add values into the array, using the sum of the last two values, except for the first two.
const fibonacci = n =>
  Array.from({ length: n }).reduce(
    (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),
    []
  );
fibonacci(6); // [0, 1, 1, 2, 3, 5]

title: filterNonUnique

Creates an array with the non-unique values filtered out.

  • Use new Set() and the spread operator (...) to create an array of the unique values in arr.
  • Use Array.prototype.filter() to create an array containing only the unique values.
const filterNonUnique = arr =>
  [...new Set(arr)].filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
filterNonUnique([1, 2, 2, 3, 4, 4, 5]); // [1, 3, 5]

title: filterNonUniqueBy

Creates an array with the non-unique values filtered out, based on a provided comparator function.

  • Use Array.prototype.filter() and Array.prototype.every() to create an array containing only the unique values, based on the comparator function, fn.
  • The comparator function takes four arguments: the values of the two elements being compared and their indexes.
const filterNonUniqueBy = (arr, fn) =>
  arr.filter((v, i) => arr.every((x, j) => (i === j) === fn(v, x, i, j)));
filterNonUniqueBy(
  [
    { id: 0, value: 'a' },
    { id: 1, value: 'b' },
    { id: 2, value: 'c' },
    { id: 1, value: 'd' },
    { id: 0, value: 'e' }
  ],
  (a, b) => a.id === b.id
); // [ { id: 2, value: 'c' } ]

title: filterUnique

Creates an array with the unique values filtered out.

  • Use new Set() and the spread operator (...) to create an array of the unique values in arr.
  • Use Array.prototype.filter() to create an array containing only the non-unique values.
const filterUnique = arr =>
  [...new Set(arr)].filter(i => arr.indexOf(i) !== arr.lastIndexOf(i));
filterUnique([1, 2, 2, 3, 4, 4, 5]); // [2, 4]

title: filterUniqueBy

Creates an array with the unique values filtered out, based on a provided comparator function.

  • Use Array.prototype.filter() and Array.prototype.every() to create an array containing only the non-unique values, based on the comparator function, fn.
  • The comparator function takes four arguments: the values of the two elements being compared and their indexes.
const filterUniqueBy = (arr, fn) =>
  arr.filter((v, i) => arr.some((x, j) => (i !== j) === fn(v, x, i, j)));
filterUniqueBy(
  [
    { id: 0, value: 'a' },
    { id: 1, value: 'b' },
    { id: 2, value: 'c' },
    { id: 3, value: 'd' },
    { id: 0, value: 'e' }
  ],
  (a, b) => a.id == b.id
); // [ { id: 0, value: 'a' }, { id: 0, value: 'e' } ]

title: findClosestAnchor

Finds the anchor node closest to the given node, if any.

  • Use a for loop and Node.parentNode to traverse the node tree upwards from the given node.
  • Use Node.nodeName and String.prototype.toLowerCase() to check if any given node is an anchor ('a').
  • If no matching node is found, return null.
const findClosestAnchor = node => {
  for (let n = node; n.parentNode; n = n.parentNode)
    if (n.nodeName.toLowerCase() === 'a') return n;
  return null;
};
findClosestAnchor(document.querySelector('a > span')); // a

title: findClosestMatchingNode

Finds the closest matching node starting at the given node.

  • Use a for loop and Node.parentNode to traverse the node tree upwards from the given node.
  • Use Element.matches() to check if any given element node matches the provided selector.
  • If no matching node is found, return null.
const findClosestMatchingNode = (node, selector) => {
  for (let n = node; n.parentNode; n = n.parentNode)
    if (n.matches && n.matches(selector)) return n;
  return null;
};
findClosestMatchingNode(document.querySelector('span'), 'body'); // body

title: findFirstN

Finds the first n elements for which the provided function returns a truthy value.

  • Use a for..in loop to execute the provided matcher for each element of arr.
  • Use Array.prototype.push() to append elements to the results array and return them if its length is equal to n.
const findFirstN = (arr, matcher, n = 1) => {
  let res = [];
  for (let i in arr) {
    const el = arr[i];
    const match = matcher(el, i, arr);
    if (match) res.push(el);
    if (res.length === n) return res;
  }
  return res;
};
findFirstN([1, 2, 4, 6], n => n % 2 === 0, 2); // [2, 4]
findFirstN([1, 2, 4, 6], n => n % 2 === 0, 5); // [2, 4, 6]

title: findKey

Finds the first key that satisfies the provided testing function. Otherwise undefined is returned.

  • Use Object.keys(obj) to get all the properties of the object, Array.prototype.find() to test each key-value pair using fn.
  • The callback receives three arguments - the value, the key and the object.
const findKey = (obj, fn) => 
  Object.keys(obj).find(key => fn(obj[key], key, obj));
findKey(
  {
    barney: { age: 36, active: true },
    fred: { age: 40, active: false },
    pebbles: { age: 1, active: true }
  },
  x => x['active']
); // 'barney'

title: findKeys

Finds all the keys in the provided object that match the given value.

  • Use Object.keys(obj) to get all the properties of the object.
  • Use Array.prototype.filter() to test each key-value pair and return all keys that are equal to the given value.
const findKeys = (obj, val) => 
  Object.keys(obj).filter(key => obj[key] === val);
const ages = {
  Leo: 20,
  Zoey: 21,
  Jane: 20,
};
findKeys(ages, 20); // [ 'Leo', 'Jane' ]

title: findLast

Finds the last element for which the provided function returns a truthy value.

  • Use Array.prototype.filter() to remove elements for which fn returns falsy values.
  • Use Array.prototype.pop() to get the last element in the filtered array.
const findLast = (arr, fn) => arr.filter(fn).pop();
findLast([1, 2, 3, 4], n => n % 2 === 1); // 3

title: findLastIndex

Finds the index of the last element for which the provided function returns a truthy value.

  • Use Array.prototype.map() to map each element to an array with its index and value.
  • Use Array.prototype.filter() to remove elements for which fn returns falsy values
  • Use Array.prototype.pop() to get the last element in the filtered array.
  • Return -1 if there are no matching elements.
const findLastIndex = (arr, fn) =>
  (arr
    .map((val, i) => [i, val])
    .filter(([i, val]) => fn(val, i, arr))
    .pop() || [-1])[0];
findLastIndex([1, 2, 3, 4], n => n % 2 === 1); // 2 (index of the value 3)
findLastIndex([1, 2, 3, 4], n => n === 5); // -1 (default value when not found)

title: findLastKey

Finds the last key that satisfies the provided testing function. Otherwise undefined is returned.

  • Use Object.keys(obj) to get all the properties of the object.
  • Use Array.prototype.reverse() to reverse the order and Array.prototype.find() to test the provided function for each key-value pair.
  • The callback receives three arguments - the value, the key and the object.
const findLastKey = (obj, fn) =>
  Object.keys(obj)
    .reverse()
    .find(key => fn(obj[key], key, obj));
findLastKey(
  {
    barney: { age: 36, active: true },
    fred: { age: 40, active: false },
    pebbles: { age: 1, active: true }
  },
  x => x['active']
); // 'pebbles'

title: findLastN

Finds the last n elements for which the provided function returns a truthy value.

  • Use a for loop to execute the provided matcher for each element of arr.
  • Use Array.prototype.unshift() to prepend elements to the results array and return them if its length is equal to n.
const findLastN = (arr, matcher, n = 1) => {
  let res = [];
  for (let i = arr.length - 1; i >= 0; i--) {
    const el = arr[i];
    const match = matcher(el, i, arr);
    if (match) res.unshift(el);
    if (res.length === n) return res;
  }
  return res;
};
findLastN([1, 2, 4, 6], n => n % 2 === 0, 2); // [4, 6]
findLastN([1, 2, 4, 6], n => n % 2 === 0, 5); // [2, 4, 6]

title: flatten

Flattens an array up to the specified depth.

  • Use recursion, decrementing depth by 1 for each level of depth.
  • Use Array.prototype.reduce() and Array.prototype.concat() to merge elements or arrays.
  • Base case, for depth equal to 1 stops recursion.
  • Omit the second argument, depth, to flatten only to a depth of 1 (single flatten).
const flatten = (arr, depth = 1) =>
  arr.reduce(
    (a, v) =>
      a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v),
    []
  );
flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]

title: flattenObject

Flattens an object with the paths for keys.

  • Use recursion.
  • Use Object.keys(obj) combined with Array.prototype.reduce() to convert every leaf node to a flattened path node.
  • If the value of a key is an object, the function calls itself with the appropriate prefix to create the path using Object.assign().
  • Otherwise, it adds the appropriate prefixed key-value pair to the accumulator object.
  • You should always omit the second argument, prefix, unless you want every key to have a prefix.
const flattenObject = (obj, prefix = '') =>
  Object.keys(obj).reduce((acc, k) => {
    const pre = prefix.length ? `${prefix}.` : '';
    if (
      typeof obj[k] === 'object' &&
      obj[k] !== null &&
      Object.keys(obj[k]).length > 0
    )
      Object.assign(acc, flattenObject(obj[k], pre + k));
    else acc[pre + k] = obj[k];
    return acc;
  }, {});
flattenObject({ a: { b: { c: 1 } }, d: 1 }); // { 'a.b.c': 1, d: 1 }

title: flip

Takes a function as an argument, then makes the first argument the last.

  • Use argument destructuring and a closure with variadic arguments.
  • Splice the first argument, using the spread operator (...), to make it the last before applying the rest.
const flip = fn => (first, ...rest) => fn(...rest, first);
let a = { name: 'John Smith' };
let b = {};
const mergeFrom = flip(Object.assign);
let mergePerson = mergeFrom.bind(null, a);
mergePerson(b); // == b
b = {};
Object.assign(b, a); // == b

title: forEachRight

Executes a provided function once for each array element, starting from the array's last element.

  • Use Array.prototype.slice() to clone the given array and Array.prototype.reverse() to reverse it.
  • Use Array.prototype.forEach() to iterate over the reversed array.
const forEachRight = (arr, callback) =>
  arr
    .slice()
    .reverse()
    .forEach(callback);
forEachRight([1, 2, 3, 4], val => console.log(val)); // '4', '3', '2', '1'

title: forOwn

Iterates over all own properties of an object, running a callback for each one.

  • Use Object.keys(obj) to get all the properties of the object.
  • Use Array.prototype.forEach() to run the provided function for each key-value pair.
  • The callback receives three arguments - the value, the key and the object.
const forOwn = (obj, fn) =>
  Object.keys(obj).forEach(key => fn(obj[key], key, obj));
forOwn({ foo: 'bar', a: 1 }, v => console.log(v)); // 'bar', 1

title: forOwnRight

Iterates over all own properties of an object in reverse, running a callback for each one.

  • Use Object.keys(obj) to get all the properties of the object, Array.prototype.reverse() to reverse their order.
  • Use Array.prototype.forEach() to run the provided function for each key-value pair.
  • The callback receives three arguments - the value, the key and the object.
const forOwnRight = (obj, fn) =>
  Object.keys(obj)
    .reverse()
    .forEach(key => fn(obj[key], key, obj));
forOwnRight({ foo: 'bar', a: 1 }, v => console.log(v)); // 1, 'bar'

title: formToObject

Encodes a set of form elements as an object.

  • Use the FormData constructor to convert the HTML form to FormData and Array.from() to convert to an array.
  • Collect the object from the array using Array.prototype.reduce().
const formToObject = form =>
  Array.from(new FormData(form)).reduce(
    (acc, [key, value]) => ({
      ...acc,
      [key]: value
    }),
    {}
  );
formToObject(document.querySelector('#form'));
// { email: 'test@email.com', name: 'Test Name' }

title: formatDuration

Returns the human-readable format of the given number of milliseconds.

  • Divide ms with the appropriate values to obtain the appropriate values for day, hour, minute, second and millisecond.
  • Use Object.entries() with Array.prototype.filter() to keep only non-zero values.
  • Use Array.prototype.map() to create the string for each value, pluralizing appropriately.
  • Use String.prototype.join(', ') to combine the values into a string.
const formatDuration = ms => {
  if (ms < 0) ms = -ms;
  const time = {
    day: Math.floor(ms / 86400000),
    hour: Math.floor(ms / 3600000) % 24,
    minute: Math.floor(ms / 60000) % 60,
    second: Math.floor(ms / 1000) % 60,
    millisecond: Math.floor(ms) % 1000
  };
  return Object.entries(time)
    .filter(val => val[1] !== 0)
    .map(([key, val]) => `${val} ${key}${val !== 1 ? 's' : ''}`)
    .join(', ');
};
formatDuration(1001); // '1 second, 1 millisecond'
formatDuration(34325055574);
// '397 days, 6 hours, 44 minutes, 15 seconds, 574 milliseconds'

title: formatNumber

Formats a number using the local number format order.

  • Use Number.prototype.toLocaleString() to convert a number to using the local number format separators.
const formatNumber = num => num.toLocaleString();
formatNumber(123456); // '123,456' in `en-US`
formatNumber(15675436903); // '15.675.436.903' in `de-DE`

title: formatSeconds

Returns the ISO format of the given number of seconds.

  • Divide s with the appropriate values to obtain the appropriate values for hour, minute and second.
  • Store the sign in a variable to prepend it to the result.
  • Use Array.prototype.map() in combination with Math.floor() and String.prototype.padStart() to stringify and format each segment.
  • Use String.prototype.join(':') to combine the values into a string.
const formatSeconds = s => {
  const [hour, minute, second, sign] =
    s > 0
      ? [s / 3600, (s / 60) % 60, s % 60, '']
      : [-s / 3600, (-s / 60) % 60, -s % 60, '-'];

  return (
    sign +
    [hour, minute, second]
      .map(v => `${Math.floor(v)}`.padStart(2, '0'))
      .join(':')
  );
};
formatSeconds(200); // '00:03:20'
formatSeconds(-200); // '-00:03:20'
formatSeconds(99999); // '27:46:39'

title: frequencies

Creates an object with the unique values of an array as keys and their frequencies as the values.

  • Use Array.prototype.reduce() to map unique values to an object's keys, adding to existing keys every time the same value is encountered.
const frequencies = arr =>
  arr.reduce((a, v) => {
    a[v] = a[v] ? a[v] + 1 : 1;
    return a;
  }, {});
frequencies(['a', 'b', 'a', 'c', 'a', 'a', 'b']); // { a: 4, b: 2, c: 1 }
frequencies([...'ball']); // { b: 1, a: 1, l: 2 }

title: fromCamelCase

Converts a string from camelcase.

  • Use String.prototype.replace() to break the string into words and add a separator between them.
  • Omit the second argument to use a default separator of _.
const fromCamelCase = (str, separator = '_') =>
  str
    .replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2')
    .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2')
    .toLowerCase();
fromCamelCase('someDatabaseFieldName', ' '); // 'some database field name'
fromCamelCase('someLabelThatNeedsToBeDecamelized', '-'); 
// 'some-label-that-needs-to-be-decamelized'
fromCamelCase('someJavascriptProperty', '_'); // 'some_javascript_property'
fromCamelCase('JSONToCSV', '.'); // 'json.to.csv'

title: fromTimestamp

Creates a Date object from a Unix timestamp.

  • Convert the timestamp to milliseconds by multiplying with 1000.
  • Use new Date() to create a new Date object.
const fromTimestamp = timestamp => new Date(timestamp * 1000);
fromTimestamp(1602162242); // 2020-10-08T13:04:02.000Z

title: frozenSet

Creates a frozen Set object.

  • Use the new Set() constructor to create a new Set object from iterable.
  • Set the add, delete and clear methods of the newly created object to undefined, so that they cannot be used, practically freezing the object.
const frozenSet = iterable => {
  const s = new Set(iterable);
  s.add = undefined;
  s.delete = undefined;
  s.clear = undefined;
  return s;
};
frozenSet([1, 2, 3, 1, 2]); 
// Set { 1, 2, 3, add: undefined, delete: undefined, clear: undefined }

title: fullscreen

Opens or closes an element in fullscreen mode.

  • Use Document.querySelector() and Element.requestFullscreen() to open the given element in fullscreen.
  • Use Document.exitFullscreen() to exit fullscreen mode.
  • Omit the second argument, el, to use body as the default element.
  • Omit the first element, mode, to open the element in fullscreen mode by default.
const fullscreen = (mode = true, el = 'body') =>
  mode
    ? document.querySelector(el).requestFullscreen()
    : document.exitFullscreen();
fullscreen(); // Opens `body` in fullscreen mode
fullscreen(false); // Exits fullscreen mode

title: functionName

Logs the name of a function.

  • Use console.debug() and the name property of the passed function to log the function's name to the debug channel of the console.
  • Return the given function fn.
const functionName = fn => (console.debug(fn.name), fn);
let m = functionName(Math.max)(5, 6);
// max (logged in debug channel of console)
// m = 6

title: functions

Gets an array of function property names from own (and optionally inherited) enumerable properties of an object.

  • Use Object.keys(obj) to iterate over the object's own properties.
  • If inherited is true, use Object.getPrototypeOf(obj) to also get the object's inherited properties.
  • Use Array.prototype.filter() to keep only those properties that are functions.
  • Omit the second argument, inherited, to not include inherited properties by default.
const functions = (obj, inherited = false) =>
  (inherited
    ? [...Object.keys(obj), ...Object.keys(Object.getPrototypeOf(obj))]
    : Object.keys(obj)
  ).filter(key => typeof obj[key] === 'function');
function Foo() {
  this.a = () => 1;
  this.b = () => 2;
}
Foo.prototype.c = () => 3;
functions(new Foo()); // ['a', 'b']
functions(new Foo(), true); // ['a', 'b', 'c']

title: gcd

Calculates the greatest common divisor between two or more numbers/arrays.

  • The inner _gcd function uses recursion.
  • Base case is when y equals 0. In this case, return x.
  • Otherwise, return the GCD of y and the remainder of the division x/y.
const gcd = (...arr) => {
  const _gcd = (x, y) => (!y ? x : gcd(y, x % y));
  return [...arr].reduce((a, b) => _gcd(a, b));
};
gcd(8, 36); // 4
gcd(...[12, 8, 32]); // 4

title: generateItems

Generates an array with the given amount of items, using the given function.

  • Use Array.from() to create an empty array of the specific length, calling fn with the index of each newly created element.
  • The callback takes one argument - the index of each element.
const generateItems = (n, fn) => Array.from({ length: n }, (_, i) => fn(i));
generateItems(10, Math.random);
// [0.21, 0.08, 0.40, 0.96, 0.96, 0.24, 0.19, 0.96, 0.42, 0.70]

title: generatorToArray

Converts the output of a generator function to an array.

  • Use the spread operator (...) to convert the output of the generator function to an array.
const generatorToArray = gen => [...gen];
const s = new Set([1, 2, 1, 3, 1, 4]);
generatorToArray(s.entries()); // [[ 1, 1 ], [ 2, 2 ], [ 3, 3 ], [ 4, 4 ]]

title: geometricProgression

Initializes an array containing the numbers in the specified range where start and end are inclusive and the ratio between two terms is step. Returns an error if step equals 1.

  • Use Array.from(), Math.log() and Math.floor() to create an array of the desired length, Array.prototype.map() to fill with the desired values in a range.
  • Omit the second argument, start, to use a default value of 1.
  • Omit the third argument, step, to use a default value of 2.
const geometricProgression = (end, start = 1, step = 2) =>
  Array.from({
    length: Math.floor(Math.log(end / start) / Math.log(step)) + 1,
  }).map((_, i) => start * step ** i);
geometricProgression(256); // [1, 2, 4, 8, 16, 32, 64, 128, 256]
geometricProgression(256, 3); // [3, 6, 12, 24, 48, 96, 192]
geometricProgression(256, 1, 4); // [1, 4, 16, 64, 256]

title: get

Retrieves a set of properties indicated by the given selectors from an object.

  • Use Array.prototype.map() for each selector, String.prototype.replace() to replace square brackets with dots.
  • Use String.prototype.split('.') to split each selector.
  • Use Array.prototype.filter() to remove empty values and Array.prototype.reduce() to get the value indicated by each selector.
const get = (from, ...selectors) =>
  [...selectors].map(s =>
    s
      .replace(/\[([^\[\]]*)\]/g, '.$1.')
      .split('.')
      .filter(t => t !== '')
      .reduce((prev, cur) => prev && prev[cur], from)
  );
const obj = {
  selector: { to: { val: 'val to select' } },
  target: [1, 2, { a: 'test' }],
};
get(obj, 'selector.to.val', 'target[0]', 'target[2].a');
// ['val to select', 1, 'test']

title: getAncestors

Returns all the ancestors of an element from the document root to the given element.

  • Use Node.parentNode and a while loop to move up the ancestor tree of the element.
  • Use Array.prototype.unshift() to add each new ancestor to the start of the array.
const getAncestors = el => {
  let ancestors = [];
  while (el) {
    ancestors.unshift(el);
    el = el.parentNode;
  }
  return ancestors;
};
getAncestors(document.querySelector('nav')); 
// [document, html, body, header, nav]

title: getBaseURL

Gets the current URL without any parameters or fragment identifiers.

  • Use String.prototype.replace() with an appropriate regular expression to remove everything after either '?' or '#', if found.
const getBaseURL = url => url.replace(/[?#].*$/, '');
getBaseURL('http://url.com/page?name=Adam&surname=Smith');
// 'http://url.com/page'

title: getColonTimeFromDate

Returns a string of the form HH:MM:SS from a Date object.

  • Use Date.prototype.toTimeString() and String.prototype.slice() to get the HH:MM:SS part of a given Date object.
const getColonTimeFromDate = date => date.toTimeString().slice(0, 8);
getColonTimeFromDate(new Date()); // '08:38:00'

title: getDaysDiffBetweenDates

Calculates the difference (in days) between two dates.

  • Subtract the two Date objects and divide by the number of milliseconds in a day to get the difference (in days) between them.
const getDaysDiffBetweenDates = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / (1000 * 3600 * 24);
getDaysDiffBetweenDates(new Date('2017-12-13'), new Date('2017-12-22')); // 9

title: getElementsBiggerThanViewport

Returns an array of HTML elements whose width is larger than that of the viewport's.

  • Use HTMLElement.offsetWidth to get the width of the document.
  • Use Array.prototype.filter() on the result of Document.querySelectorAll() to check the width of all elements in the document.
const getElementsBiggerThanViewport = () => {
  const docWidth = document.documentElement.offsetWidth;
  return [...document.querySelectorAll('*')].filter(
    el => el.offsetWidth > docWidth
  );
};
getElementsBiggerThanViewport(); // <div id="ultra-wide-item" />

title: getHoursDiffBetweenDates

Calculates the difference (in hours) between two dates.

  • Subtract the two Date objects and divide by the number of milliseconds in an hour to get the difference (in hours) between them.
const getHoursDiffBetweenDates = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / (1000 * 3600);
getHoursDiffBetweenDates(
  new Date('2021-04-24 10:25:00'),
  new Date('2021-04-25 10:25:00')
); // 24

title: getImages

Fetches all images from within an element and puts them into an array.

  • Use Element.getElementsByTagName() to get all <img> elements inside the provided element.
  • Use Array.prototype.map() to map every src attribute of each <img> element.
  • If includeDuplicates is false, create a new Set to eliminate duplicates and return it after spreading into an array.
  • Omit the second argument, includeDuplicates, to discard duplicates by default.
const getImages = (el, includeDuplicates = false) => {
  const images = [...el.getElementsByTagName('img')].map(img =>
    img.getAttribute('src')
  );
  return includeDuplicates ? images : [...new Set(images)];
};
getImages(document, true); // ['image1.jpg', 'image2.png', 'image1.png', '...']
getImages(document, false); // ['image1.jpg', 'image2.png', '...']

title: getMeridiemSuffixOfInteger

Converts an integer to a suffixed string, adding am or pm based on its value.

  • Use the modulo operator (%) and conditional checks to transform an integer to a stringified 12-hour format with meridiem suffix.
const getMeridiemSuffixOfInteger = num =>
  num === 0 || num === 24
    ? 12 + 'am'
    : num === 12
    ? 12 + 'pm'
    : num < 12
    ? (num % 12) + 'am'
    : (num % 12) + 'pm';
getMeridiemSuffixOfInteger(0); // '12am'
getMeridiemSuffixOfInteger(11); // '11am'
getMeridiemSuffixOfInteger(13); // '1pm'
getMeridiemSuffixOfInteger(25); // '1pm'

title: getMinutesDiffBetweenDates

Calculates the difference (in minutes) between two dates.

  • Subtract the two Date objects and divide by the number of milliseconds in a minute to get the difference (in minutes) between them.
const getMinutesDiffBetweenDates = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / (1000 * 60);
getMinutesDiffBetweenDates(
  new Date('2021-04-24 01:00:15'),
  new Date('2021-04-24 02:00:15')
); // 60

title: getMonthsDiffBetweenDates

Calculates the difference (in months) between two dates.

  • Use Date.prototype.getFullYear() and Date.prototype.getMonth() to calculate the difference (in months) between two Date objects.
const getMonthsDiffBetweenDates = (dateInitial, dateFinal) =>
  Math.max(
    (dateFinal.getFullYear() - dateInitial.getFullYear()) * 12 +
      dateFinal.getMonth() -
      dateInitial.getMonth(),
    0
  );
getMonthsDiffBetweenDates(new Date('2017-12-13'), new Date('2018-04-29')); // 4

title: getParentsUntil

Finds all the ancestors of an element up until the element matched by the specified selector.

  • Use Node.parentNode and a while loop to move up the ancestor tree of the element.
  • Use Array.prototype.unshift() to add each new ancestor to the start of the array.
  • Use Element.matches() to check if the current element matches the specified selector.
const getParentsUntil = (el, selector) => {
  let parents = [],
    _el = el.parentNode;
  while (_el && typeof _el.matches === 'function') {
    parents.unshift(_el);
    if (_el.matches(selector)) return parents;
    else _el = _el.parentNode;
  }
  return [];
};
getParentsUntil(document.querySelector('#home-link'), 'header');
// [header, nav, ul, li]

title: getProtocol

Gets the protocol being used on the current page.

  • Use Window.location.protocol to get the protocol (http: or https:) of the current page.
const getProtocol = () => window.location.protocol;
getProtocol(); // 'https:'

title: getScrollPosition

Returns the scroll position of the current page.

  • Use Window.pageXOffset and Window.pageYOffset if they are defined, otherwise Element.scrollLeft and Element.scrollTop.
  • Omit the single argument, el, to use a default value of window.
const getScrollPosition = (el = window) => ({
  x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
getScrollPosition(); // {x: 0, y: 200}

title: getSecondsDiffBetweenDates

Calculates the difference (in seconds) between two dates.

  • Subtract the two Date objects and divide by the number of milliseconds in a second to get the difference (in seconds) between them.
const getSecondsDiffBetweenDates = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / 1000;
getSecondsDiffBetweenDates(
  new Date('2020-12-24 00:00:15'),
  new Date('2020-12-24 00:00:17')
); // 2

title: getSelectedText

Gets the currently selected text.

  • Use Window.getSelection() and Selection.toString() to get the currently selected text.
const getSelectedText = () => window.getSelection().toString();
getSelectedText(); // 'Lorem ipsum'

title: getSiblings

Returns an array containing all the siblings of the given element.

  • Use Node.parentNode and Node.childNodes to get a NodeList of all the elements contained in the element's parent.
  • Use the spread operator (...) and Array.prototype.filter() to convert to an array and remove the given element from it.
const getSiblings = el =>
  [...el.parentNode.childNodes].filter(node => node !== el);
getSiblings(document.querySelector('head')); // ['body']

title: getStyle

Retrieves the value of a CSS rule for the specified element.

  • Use Window.getComputedStyle() to get the value of the CSS rule for the specified element.
const getStyle = (el, ruleName) => getComputedStyle(el)[ruleName];
getStyle(document.querySelector('p'), 'font-size'); // '16px'

title: getTimestamp

Gets the Unix timestamp from a Date object.

  • Use Date.prototype.getTime() to get the timestamp in milliseconds and divide by 1000 to get the timestamp in seconds.
  • Use Math.floor() to appropriately round the resulting timestamp to an integer.
  • Omit the argument, date, to use the current date.
const getTimestamp = (date = new Date()) => Math.floor(date.getTime() / 1000);
getTimestamp(); // 1602162242

title: getType

Returns the native type of a value.

  • Return 'undefined' or 'null' if the value is undefined or null.
  • Otherwise, use Object.prototype.constructor.name to get the name of the constructor.
const getType = v =>
  (v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name);
getType(new Set([1, 2, 3])); // 'Set'

title: getURLParameters

Creates an object containing the parameters of the current URL.

  • Use String.prototype.match() with an appropriate regular expression to get all key-value pairs.
  • Use Array.prototype.reduce() to map and combine them into a single object.
  • Pass location.search as the argument to apply to the current url.
const getURLParameters = url =>
  (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
    (a, v) => (
      (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a
    ),
    {}
  );
getURLParameters('google.com'); // {}
getURLParameters('http://url.com/page?name=Adam&surname=Smith');
// {name: 'Adam', surname: 'Smith'}

title: getVerticalOffset

Finds the distance from a given element to the top of the document.

  • Use a while loop and HTMLElement.offsetParent to move up the offset parents of the given element.
  • Add HTMLElement.offsetTop for each element and return the result.
const getVerticalOffset = el => {
  let offset = el.offsetTop,
    _el = el;
  while (_el.offsetParent) {
    _el = _el.offsetParent;
    offset += _el.offsetTop;
  }
  return offset;
};
getVerticalOffset('.my-element'); // 120

title: groupBy

Groups the elements of an array based on the given function.

  • Use Array.prototype.map() to map the values of the array to a function or property name.
  • Use Array.prototype.reduce() to create an object, where the keys are produced from the mapped results.
const groupBy = (arr, fn) =>
  arr
    .map(typeof fn === 'function' ? fn : val => val[fn])
    .reduce((acc, val, i) => {
      acc[val] = (acc[val] || []).concat(arr[i]);
      return acc;
    }, {});
groupBy([6.1, 4.2, 6.3], Math.floor); // {4: [4.2], 6: [6.1, 6.3]}
groupBy(['one', 'two', 'three'], 'length'); // {3: ['one', 'two'], 5: ['three']}

title: hammingDistance

Calculates the Hamming distance between two values.

  • Use the XOR operator (^) to find the bit difference between the two numbers.
  • Convert to a binary string using Number.prototype.toString(2).
  • Count and return the number of 1s in the string, using String.prototype.match(/1/g).
const hammingDistance = (num1, num2) =>
  ((num1 ^ num2).toString(2).match(/1/g) || '').length;
hammingDistance(2, 3); // 1

title: hasClass

Checks if the given element has the specified class.

  • Use Element.classList and DOMTokenList.contains() to check if the element has the specified class.
const hasClass = (el, className) => el.classList.contains(className);
hasClass(document.querySelector('p.special'), 'special'); // true

title: hasDuplicates

Checks if there are duplicate values in a flat array.

  • Use Set() to get the unique values in the array.
  • Use Set.prototype.size and Array.prototype.length to check if the count of the unique values is the same as elements in the original array.
const hasDuplicates = arr => new Set(arr).size !== arr.length;
hasDuplicates([0, 1, 1, 2]); // true
hasDuplicates([0, 1, 2, 3]); // false

title: hasFlags

Checks if the current process's arguments contain the specified flags.

  • Use Array.prototype.every() and Array.prototype.includes() to check if process.argv contains all the specified flags.
  • Use a regular expression to test if the specified flags are prefixed with - or -- and prefix them accordingly.
const hasFlags = (...flags) =>
  flags.every(flag =>
    process.argv.includes(/^-{1,2}/.test(flag) ? flag : '--' + flag)
  );
// node myScript.js -s --test --cool=true
hasFlags('-s'); // true
hasFlags('--test', 'cool=true', '-s'); // true
hasFlags('special'); // false

title: hasKey

Checks if the target value exists in a JSON object.

  • Check if keys is non-empty and use Array.prototype.every() to sequentially check its keys to internal depth of the object, obj.
  • Use Object.prototype.hasOwnProperty() to check if obj does not have the current key or is not an object, stop propagation and return false.
  • Otherwise assign the key's value to obj to use on the next iteration.
  • Return false beforehand if given key list is empty.
const hasKey = (obj, keys) => {
  return (
    keys.length > 0 &&
    keys.every(key => {
      if (typeof obj !== 'object' || !obj.hasOwnProperty(key)) return false;
      obj = obj[key];
      return true;
    })
  );
};
let obj = {
  a: 1,
  b: { c: 4 },
  'b.d': 5
};
hasKey(obj, ['a']); // true
hasKey(obj, ['b']); // true
hasKey(obj, ['b', 'c']); // true
hasKey(obj, ['b.d']); // true
hasKey(obj, ['d']); // false
hasKey(obj, ['c']); // false
hasKey(obj, ['b', 'f']); // false

title: hasMany

Checks if an array has more than one value matching the given function.

  • Use Array.prototype.filter() in combination with fn to find all matching array elements.
  • Use Array.prototype.length to check if more than one element match fn.
const hasMany = (arr, fn) => arr.filter(fn).length > 1;
hasMany([1, 3], x => x % 2); // true
hasMany([1, 2], x => x % 2); // false

title: hasOne

Checks if an array has only one value matching the given function.

  • Use Array.prototype.filter() in combination with fn to find all matching array elements.
  • Use Array.prototype.length to check if only one element matches fn.
const hasOne = (arr, fn) => arr.filter(fn).length === 1;
hasOne([1, 2], x => x % 2); // true
hasOne([1, 3], x => x % 2); // false

title: hashBrowser

Creates a hash for a value using the SHA-256 algorithm. Returns a promise.

  • Use the SubtleCrypto API to create a hash for the given value.
  • Create a new TextEncoder and use it to encode val. Pass its value to SubtleCrypto.digest() to generate a digest of the given data.
  • Use DataView.prototype.getUint32() to read data from the resolved ArrayBuffer.
  • Convert the data to it hexadecimal representation using Number.prototype.toString(16). Add the data to an array using Array.prototype.push().
  • Finally, use Array.prototype.join() to combine values in the array of hexes into a string.
const hashBrowser = val =>
  crypto.subtle
    .digest('SHA-256', new TextEncoder('utf-8').encode(val))
    .then(h => {
      let hexes = [],
        view = new DataView(h);
      for (let i = 0; i < view.byteLength; i += 4)
        hexes.push(('00000000' + view.getUint32(i).toString(16)).slice(-8));
      return hexes.join('');
    });
hashBrowser(
  JSON.stringify({ a: 'a', b: [1, 2, 3, 4], foo: { c: 'bar' } })
).then(console.log);
// '04aa106279f5977f59f9067fa9712afc4aedc6f5862a8defc34552d8c7206393'

title: hashNode

Creates a hash for a value using the SHA-256 algorithm. Returns a promise.

  • Use crypto.createHash() to create a Hash object with the appropriate algorithm.
  • Use hash.update() to add the data from val to the Hash, hash.digest() to calculate the digest of the data.
  • Use setTimeout() to prevent blocking on a long operation. Return a Promise to give it a familiar interface.
const crypto = require('crypto');

const hashNode = val =>
  new Promise(resolve =>
    setTimeout(
      () => resolve(crypto.createHash('sha256').update(val).digest('hex')),
      0
    )
  );
hashNode(JSON.stringify({ a: 'a', b: [1, 2, 3, 4], foo: { c: 'bar' } })).then(
  console.log
);
// '04aa106279f5977f59f9067fa9712afc4aedc6f5862a8defc34552d8c7206393'

title: haveSameContents

Checks if two arrays contain the same elements regardless of order.

  • Use a for...of loop over a Set created from the values of both arrays.
  • Use Array.prototype.filter() to compare the amount of occurrences of each distinct value in both arrays.
  • Return false if the counts do not match for any element, true otherwise.
const haveSameContents = (a, b) => {
  for (const v of new Set([...a, ...b]))
    if (a.filter(e => e === v).length !== b.filter(e => e === v).length)
      return false;
  return true;
};
haveSameContents([1, 2, 4], [2, 4, 1]); // true

title: head

Returns the head of an array.

  • Check if arr is truthy and has a length property.
  • Use arr[0] if possible to return the first element, otherwise return undefined.
const head = arr => (arr && arr.length ? arr[0] : undefined);
head([1, 2, 3]); // 1
head([]); // undefined
head(null); // undefined
head(undefined); // undefined

title: heapsort

Sorts an array of numbers, using the heapsort algorithm.

  • Use recursion.
  • Use the spread operator (...) to clone the original array, arr.
  • Use closures to declare a variable, l, and a function heapify.
  • Use a for loop and Math.floor() in combination with heapify to create a max heap from the array.
  • Use a for loop to repeatedly narrow down the considered range, using heapify and swapping values as necessary in order to sort the cloned array.
const heapsort = arr => {
  const a = [...arr];
  let l = a.length;

  const heapify = (a, i) => {
    const left = 2 * i + 1;
    const right = 2 * i + 2;
    let max = i;
    if (left < l && a[left] > a[max]) max = left;
    if (right < l && a[right] > a[max]) max = right;
    if (max !== i) {
      [a[max], a[i]] = [a[i], a[max]];
      heapify(a, max);
    }
  };

  for (let i = Math.floor(l / 2); i >= 0; i -= 1) heapify(a, i);
  for (i = a.length - 1; i > 0; i--) {
    [a[0], a[i]] = [a[i], a[0]];
    l--;
    heapify(a, 0);
  }
  return a;
};
heapsort([6, 3, 4, 1]); // [1, 3, 4, 6]

title: hexToRGB

Converts a color code to an rgb() or rgba() string if alpha value is provided.

  • Use bitwise right-shift operator and mask bits with & (and) operator to convert a hexadecimal color code (with or without prefixed with #) to a string with the RGB values.
  • If it's 3-digit color code, first convert to 6-digit version.
  • If an alpha value is provided alongside 6-digit hex, give rgba() string in return.
const hexToRGB = hex => {
  let alpha = false,
    h = hex.slice(hex.startsWith('#') ? 1 : 0);
  if (h.length === 3) h = [...h].map(x => x + x).join('');
  else if (h.length === 8) alpha = true;
  h = parseInt(h, 16);
  return (
    'rgb' +
    (alpha ? 'a' : '') +
    '(' +
    (h >>> (alpha ? 24 : 16)) +
    ', ' +
    ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) +
    ', ' +
    ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) +
    (alpha ? `, ${h & 0x000000ff}` : '') +
    ')'
  );
};
hexToRGB('#27ae60ff'); // 'rgba(39, 174, 96, 255)'
hexToRGB('27ae60'); // 'rgb(39, 174, 96)'
hexToRGB('#fff'); // 'rgb(255, 255, 255)'

title: hide

Hides all the elements specified.

  • Use the spread operator (...) and Array.prototype.forEach() to apply display: none to each element specified.
const hide = (...el) => [...el].forEach(e => (e.style.display = 'none'));
hide(...document.querySelectorAll('img')); // Hides all <img> elements on the page

title: httpDelete

Makes a DELETE request to the passed URL.

  • Use the XMLHttpRequest web API to make a DELETE request to the given url.
  • Handle the onload event, by running the provided callback function.
  • Handle the onerror event, by running the provided err function.
  • Omit the third argument, err to log the request to the console's error stream by default.
const httpDelete = (url, callback, err = console.error) => {
  const request = new XMLHttpRequest();
  request.open('DELETE', url, true);
  request.onload = () => callback(request);
  request.onerror = () => err(request);
  request.send();
};
httpDelete('https://jsonplaceholder.typicode.com/posts/1', request => {
  console.log(request.responseText);
}); // Logs: {}

title: httpGet

Makes a GET request to the passed URL.

  • Use the XMLHttpRequest web API to make a GET request to the given url.
  • Handle the onload event, by calling the given callback the responseText.
  • Handle the onerror event, by running the provided err function.
  • Omit the third argument, err, to log errors to the console's error stream by default.
const httpGet = (url, callback, err = console.error) => {
  const request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.onload = () => callback(request.responseText);
  request.onerror = () => err(request);
  request.send();
};
httpGet(
  'https://jsonplaceholder.typicode.com/posts/1',
  console.log
); /*
Logs: {
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
*/

title: httpPost

Makes a POST request to the passed URL.

  • Use the XMLHttpRequest web API to make a POST request to the given url.
  • Set the value of an HTTP request header with setRequestHeader method.
  • Handle the onload event, by calling the given callback the responseText.
  • Handle the onerror event, by running the provided err function.
  • Omit the fourth argument, err, to log errors to the console's error stream by default.
const httpPost = (url, data, callback, err = console.error) => {
  const request = new XMLHttpRequest();
  request.open('POST', url, true);
  request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
  request.onload = () => callback(request.responseText);
  request.onerror = () => err(request);
  request.send(data);
};
const newPost = {
  userId: 1,
  id: 1337,
  title: 'Foo',
  body: 'bar bar bar'
};
const data = JSON.stringify(newPost);
httpPost(
  'https://jsonplaceholder.typicode.com/posts',
  data,
  console.log
); /*
Logs: {
  "userId": 1,
  "id": 1337,
  "title": "Foo",
  "body": "bar bar bar"
}
*/
httpPost(
  'https://jsonplaceholder.typicode.com/posts',
  null, // does not send a body
  console.log
); /*
Logs: {
  "id": 101
}
*/

title: httpPut

Makes a PUT request to the passed URL.

  • Use XMLHttpRequest web api to make a PUT request to the given url.
  • Set the value of an HTTP request header with setRequestHeader method.
  • Handle the onload event, by running the provided callback function.
  • Handle the onerror event, by running the provided err function.
  • Omit the last argument, err to log the request to the console's error stream by default.
const httpPut = (url, data, callback, err = console.error) => {
  const request = new XMLHttpRequest();
  request.open('PUT', url, true);
  request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
  request.onload = () => callback(request);
  request.onerror = () => err(request);
  request.send(data);
};
const password = 'fooBaz';
const data = JSON.stringify({
  id: 1,
  title: 'foo',
  body: 'bar',
  userId: 1
});
httpPut('https://jsonplaceholder.typicode.com/posts/1', data, request => {
  console.log(request.responseText);
}); /*
Logs: {
  id: 1,
  title: 'foo',
  body: 'bar',
  userId: 1
}
*/

title: httpsRedirect

Redirects the page to HTTPS if it's currently in HTTP.

  • Use location.protocol to get the protocol currently being used.
  • If it's not HTTPS, use location.replace() to replace the existing page with the HTTPS version of the page.
  • Use location.href to get the full address, split it with String.prototype.split() and remove the protocol part of the URL.
  • Note that pressing the back button doesn't take it back to the HTTP page as its replaced in the history.
const httpsRedirect = () => {
  if (location.protocol !== 'https:')
    location.replace('https://' + location.href.split('//')[1]);
};
httpsRedirect(); 
// If you are on http://mydomain.com, you are redirected to https://mydomain.com

title: hz unlisted: true

Measures the number of times a function is executed per second (hz/hertz).

  • Use performance.now() to get the difference in milliseconds before and after the iteration loop to calculate the time elapsed executing the function iterations times.
  • Return the number of cycles per second by converting milliseconds to seconds and dividing it by the time elapsed.
  • Omit the second argument, iterations, to use the default of 100 iterations.
const hz = (fn, iterations = 100) => {
  const before = performance.now();
  for (let i = 0; i < iterations; i++) fn();
  return (1000 * iterations) / (performance.now() - before);
};
const numbers = Array(10000).fill().map((_, i) => i);

const sumReduce = () => numbers.reduce((acc, n) => acc + n, 0);
const sumForLoop = () => {
  let sum = 0;
  for (let i = 0; i < numbers.length; i++) sum += numbers[i];
  return sum;
};

Math.round(hz(sumReduce)); // 572
Math.round(hz(sumForLoop)); // 4784

title: inRange

Checks if the given number falls within the given range.

  • Use arithmetic comparison to check if the given number is in the specified range.
  • If the second argument, end, is not specified, the range is considered to be from 0 to start.
const inRange = (n, start, end = null) => {
  if (end && start > end) [end, start] = [start, end];
  return end == null ? n >= 0 && n < start : n >= start && n < end;
};
inRange(3, 2, 5); // true
inRange(3, 4); // true
inRange(2, 3, 5); // false
inRange(3, 2); // false

title: includesAll

Checks if all the elements in values are included in arr.

  • Use Array.prototype.every() and Array.prototype.includes() to check if all elements of values are included in arr.
const includesAll = (arr, values) => values.every(v => arr.includes(v));
includesAll([1, 2, 3, 4], [1, 4]); // true
includesAll([1, 2, 3, 4], [1, 5]); // false

title: includesAny

Checks if at least one element of values is included in arr.

  • Use Array.prototype.some() and Array.prototype.includes() to check if at least one element of values is included in arr.
const includesAny = (arr, values) => values.some(v => arr.includes(v));
includesAny([1, 2, 3, 4], [2, 9]); // true
includesAny([1, 2, 3, 4], [8, 9]); // false

title: indentString

Indents each line in the provided string.

  • Use String.prototype.replace() and a regular expression to add the character specified by indent count times at the start of each line.
  • Omit the third argument, indent, to use a default indentation character of ' '.
const indentString = (str, count, indent = ' ') =>
  str.replace(/^/gm, indent.repeat(count));
indentString('Lorem\nIpsum', 2); // '  Lorem\n  Ipsum'
indentString('Lorem\nIpsum', 2, '_'); // '__Lorem\n__Ipsum'

title: indexBy

Creates an object from an array, using a function to map each value to a key.

  • Use Array.prototype.reduce() to create an object from arr.
  • Apply fn to each value of arr to produce a key and add the key-value pair to the object.
const indexBy = (arr, fn) =>
  arr.reduce((obj, v, i) => {
    obj[fn(v, i, arr)] = v;
    return obj;
  }, {});
indexBy([
  { id: 10, name: 'apple' },
  { id: 20, name: 'orange' }
], x => x.id);
// { '10': { id: 10, name: 'apple' }, '20': { id: 20, name: 'orange' } }
const fs = require( 'fs' );
const child_process = require( 'child_process' );
const http = require( 'http' );
const path = require( 'path' );
const readline = require( 'readline' );
const url = require( 'url' );
const util = require( 'util' );
const crypto = require( 'crypto' );
const utilObj = {
'CSVToArray': function CSVToArray( data, delimiter = ',', omitFirstRow = false ) {
return data
.slice( omitFirstRow ? data.indexOf( '\n' ) + 1 : 0 )
.split( '\n' )
.map( v => v.split( delimiter ) );
},
' CSVToJSON': function CSVToJSON( data, delimiter = ',' ) {
const titles = data.slice( 0, data.indexOf( '\n' ) ).split( delimiter );
return data
.slice( data.indexOf( '\n' ) + 1 )
.split( '\n' )
.map( v => {
const values = v.split( delimiter );
return titles.reduce(
( obj, title, index ) => ( ( obj[ title ] = values[ index ] ), obj ),
{}
);
} );
},
'readfile': ,
'words': ,
'inRange': function inRange( n, start, end = null ) {
if ( end && start > end )
[ end, start ] = [ start, end ];
return end == null ? n >= 0 && n < start : n >= start && n < end;
} ,
'addClass ': function addClass( el, className ) {
return el.classList.add( className );
}
,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
'': ,
}
const utilObj = {
"anagrams": function anagrams( str ) {
if ( str.length <= 2 )
return str.length === 2 ? [ str, str[ 1 ] + str[ 0 ] ] : [ str ];
return str
.split( '' )
.reduce(
( acc, letter, i ) => acc.concat( anagrams( str.slice( 0, i ) + str.slice( i + 1 ) ).map( val => letter + val ) ),
[]
);
},
"arrayToHtmlList": function arrayToHTMLList( arr, listID ) {
return document.querySelector( `#${ listID }` ).innerHTML += arr
.map( item => `<li>${ item }</li>` )
.join( '' );
},
"ary": function ary( fn, n ) {
return ( ...args ) => fn( ...args.slice( 0, n ) );
},
"atob": function atob( str ) {
return Buffer.from( str, 'base64' ).toString( 'binary' );
},
"average": function average( ...nums ) {
return nums.reduce( ( acc, val ) => acc + val, 0 ) / nums.length;
},
"aveargeBy": function averageBy( arr, fn ) {
return arr
.map( typeof fn === 'function' ? fn : val => val[ fn ] )
.reduce( ( acc, val ) => acc + val, 0 ) / arr.length;
},
"bind": function bind( fn, context, ...args ) {
return function () {
return fn.apply( context, args.concat( ...arguments ) );
};
},
"bindAll": function bindAll( obj, ...fns ) {
return fns.forEach(
fn => (
( f = obj[ fn ] ),
( obj[ fn ] = function () {
return f.apply( obj );
} )
)
);
},
"bindKey": function bindKey( context, fn, ...boundArgs ) {
return ( ...args ) => context[ fn ].apply( context, [ ...boundArgs, ...args ] );
},
"bota": function btoa( str ) {
return new Buffer( str, 'binary' ).toString( 'base64' );
},
"bottomVisible": function bottomVisible() {
return document.documentElement.clientHeight + window.scrollY >=
( document.documentElement.scrollHeight || document.documentElement.clientHeight );
},
"byteSize": function byteSize( str ) {
return new Blob( [ str ] ).size;
},
"call": function call( key, ...args ) {
return context => context[ key ]( ...args );
},
"capitalize": function capitalize( [ first, ...rest ], lowerRest = false ) {
return first.toUpperCase() + ( lowerRest ? rest.join( '' ).toLowerCase() : rest.join( '' ) );
},
"capitalizeEveryWord": function capitalizeEveryWord( str ) {
return str.replace( /\b[a-z]/g, char => char.toUpperCase() );
},
"castArray": function castArray( val ) {
return ( Array.isArray( val ) ? val : [ val ] );
},
"chainAsync":
function chainAsync( fns ) {
let curr = 0;
const next = () => fns[ curr++ ]( next );
next();
},
"chunk": function chunk( arr, size ) {
return Array.from( { length: Math.ceil( arr.length / size ) }, ( v, i ) => arr.slice( i * size, i * size + size )
);
},
"clampNumber": function clampNumber( num, a, b ) {
return Math.max( Math.min( num, Math.max( a, b ) ), Math.min( a, b ) );
},
"cloneRegExp":
function cloneRegExp( regExp ) {
return new RegExp( regExp.source, regExp.flags );
},
"coalesce": function coalesce( ...args ) {
return args.find( _ => ![ undefined, null ].includes( _ ) );
},
"coalesceFactory": function coalesceFactory( valid ) {
return ( ...args ) => args.find( valid );
},
"collectInto": function collectInto( fn ) {
return ( ...args ) => fn( args );
},
"colorize": function colorize( ...args ) {
return ( {
black: `\\x1b[30m${ args.join( ' ' ) }`,
red: `\\x1b[31m${ args.join( ' ' ) }`,
green: `\\x1b[32m${ args.join( ' ' ) }`,
yellow: `\\x1b[33m${ args.join( ' ' ) }`,
blue: `\\x1b[34m${ args.join( ' ' ) }`,
magenta: `\\x1b[35m${ args.join( ' ' ) }`,
cyan: `\\x1b[36m${ args.join( ' ' ) }`,
white: `\\x1b[37m${ args.join( ' ' ) }`,
bgBlack: `\\x1b[40m${ args.join( ' ' ) }\\x1b[0m`,
bgRed: `\\x1b[41m${ args.join( ' ' ) }\\x1b[0m`,
bgGreen: `\\x1b[42m${ args.join( ' ' ) }\\x1b[0m`,
bgYellow: `\\x1b[43m${ args.join( ' ' ) }\\x1b[0m`,
bgBlue: `\\x1b[44m${ args.join( ' ' ) }\\x1b[0m`,
bgMagenta: `\\x1b[45m${ args.join( ' ' ) }\\x1b[0m`,
bgCyan: `\\x1b[46m${ args.join( ' ' ) }\\x1b[0m`,
bgWhite: `\\x1b[47m${ args.join( ' ' ) }\\x1b[0m`
} );
},
"compact": function compact( arr ) {
return arr.filter( Boolean );
},
"compose": function compose( ...fns ) {
return fns.reduce( ( f, g ) => ( ...args ) => f( g( ...args ) ) );
},
"composeRight": function composeRight( ...fns ) {
return fns.reduce( ( f, g ) => ( ...args ) => g( f( ...args ) ) );
},
"copyToClipboard": function copyToClipboard( str ) {
const el = document.createElement( 'textarea' );
el.value = str;
el.setAttribute( 'readonly', '' );
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild( el );
const selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt( 0 ) : false;
el.select();
document.execCommand( 'copy' );
document.body.removeChild( el );
if ( selected ) {
document.getSelection().removeAllRanges();
document.getSelection().addRange( selected );
}
},
"countBy": function countBy( arr, fn ) {
return arr.map( typeof fn === 'function' ? fn : val => val[ fn ] ).reduce( ( acc, val, i ) => {
acc[ val ] = ( acc[ val ] || 0 ) + 1;
return acc;
}, {} );
},
"countOccurrences": function countOccurrences( arr, val ) {
return arr.reduce( ( a, v ) => ( v === val ? a + 1 : a + 0 ), 0 );
},
"createElement":
function createElement( str ) {
const el = document.createElement( 'div' );
el.innerHTML = str;
return el.firstElementChild;
},
"currentUrl": function currentURL() {
return window.location.href;
},
"curry":
function curry( fn, arity = fn.length, ...args ) {
return arity <= args.length ? fn( ...args ) : curry.bind( null, fn, arity, ...args );
},
"decapitalize":
function decapitalize( [ first, ...rest ], upperRest = false ) {
return first.toLowerCase() + ( upperRest ? rest.join( '' ).toUpperCase() : rest.join( '' ) );
},
"deepClone": function deepClone( obj ) {
let clone = Object.assign( {}, obj );
Object.keys( clone ).forEach(
key => ( clone[ key ] = typeof obj[ key ] === 'object' ? deepClone( obj[ key ] ) : obj[ key ] )
);
return clone;
},
"deepFlatten": function deepFlatten( arr ) {
return [].concat( ...arr.map( v => ( Array.isArray( v ) ? deepFlatten( v ) : v ) ) );
},
"defaults": defaults
const defaults = ( obj, ...defs ) => Object.assign( {}, obj, ...defs.reverse(), obj );,
"defer": defer
const defer = ( fn, ...args ) => setTimeout( fn, 1, ...args );,
"delay": delay
const delay = ( fn, wait, ...args ) => setTimeout( fn, wait, ...args );,
"detectDeviceType": detectDeviceType
const detectDeviceType = () =>
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent )
? 'Mobile'
: 'Desktop';,
"difference": difference
const difference = ( a, b ) => {
const s = new Set( b );
return a.filter( x => !s.has( x ) );
};,
"differenceBy": differenceBy
const differenceBy = ( a, b, fn ) => {
const s = new Set( b.map( v => fn( v ) ) );
return a.filter( x => !s.has( fn( x ) ) );
};,
"differenceWith": differenceWith
const differenceWith = ( arr, val, comp ) => arr.filter( a => val.findIndex( b => comp( a, b ) ) === -1 );,
"digitize": digitize
const digitize = n => [ ...`${ n }` ].map( i => parseInt( i ) );,
"distance": distance
const distance = ( x0, y0, x1, y1 ) => Math.hypot( x1 - x0, y1 - y0 );,
"drop": drop
const drop = ( arr, n = 1 ) => arr.slice( n );,
"dropRight": dropRight
const dropRight = ( arr, n = 1 ) => arr.slice( 0, -n );,
"dropRightWhile": dropRightWhile
const dropRightWhile = ( arr, func ) => {
while ( arr.length > 0 && !func( arr[ arr.length - 1 ] ) ) arr = arr.slice( 0, -1 );
return arr;
};,
"dropWhile": dropWhile
const dropWhile = ( arr, func ) => {
while ( arr.length > 0 && !func( arr[ 0 ] ) ) arr = arr.slice( 1 );
return arr;
};,
"elementIsVisibleInViewport": elementIsVisibleInViewport
const elementIsVisibleInViewport = ( el, partiallyVisible = false ) => {
const { top, left, bottom, right } = el.getBoundingClientRect();
const { innerHeight, innerWidth } = window;
return partiallyVisible
? ( ( top > 0 && top < innerHeight ) || ( bottom > 0 && bottom < innerHeight ) ) &&
( ( left > 0 && left < innerWidth ) || ( right > 0 && right < innerWidth ) )
: top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};,
"elo": elo
const elo = ( [ ...ratings ], kFactor = 32, selfRating ) => {
const [ a, b ] = ratings;
const expectedScore = ( self, opponent ) => 1 / ( 1 + 10 ** ( ( opponent - self ) / 400 ) );
const newRating = ( rating, i ) =>
( selfRating || rating ) + kFactor * ( i - expectedScore( i ? a : b, i ? b : a ) );
if ( ratings.length === 2 ) {
return [ newRating( a, 1 ), newRating( b, 0 ) ];
} else {
for ( let i = 0; i < ratings.length; i++ ) {
let j = i;
while ( j < ratings.length - 1 ) {
[ ratings[ i ], ratings[ j + 1 ] ] = elo( [ ratings[ i ], ratings[ j + 1 ] ], kFactor );
j++;
}
}
}
return ratings;
};,
"equals": equals
const equals = ( a, b ) => {
if ( a === b )
return true;
if ( a instanceof Date && b instanceof Date )
return a.getTime() === b.getTime();
if ( !a || !b || ( typeof a != 'object' && typeof b !== 'object' ) )
return a === b;
if ( a === null || a === undefined || b === null || b === undefined )
return false;
if ( a.prototype !== b.prototype )
return false;
let keys = Object.keys( a );
if ( keys.length !== Object.keys( b ).length )
return false;
return keys.every( k => equals( a[ k ], b[ k ] ) );
};,
"escapeHTML": escapeHTML
const escapeHTML = str =>
str.replace(
/[&<>'\"]/g,
tag =>
( {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
\"'\": '&#39;',
'\"': '&quot;'
}[ tag ] || tag)
);,
"escapeRegExp": escapeRegExp
const escapeRegExp = str => str.replace( /[.*+?^${}()|[\\]\\]/g, '\\\\$&' );,
"everyNth": everyNth
const everyNth = ( arr, nth ) => arr.filter( ( e, i ) => i % nth === nth - 1 );,
"extendhex": extendhex
const extendHex = shortHex =>
'#' +
shortHex
.slice( shortHex.startsWith( '#' ) ? 1 : 0 )
.split( '' )
.map( x => x + x )
.join( '' );,
"factorial": factorial
const factorial = n =>
n < 0
? ( () => {
throw new TypeError( 'Negative numbers are not allowed!' );
} )()
: n <= 1 ? 1 : n * factorial( n - 1 );,
"fibonacci": fibonacci
const fibonacci = n =>
Array.from( { length: n } ).reduce(
( acc, val, i ) => acc.concat( i > 1 ? acc[ i - 1 ] + acc[ i - 2 ] : i ),
[]
);,
"filterNonUnique": filterNonUnique
const filterNonUnique = arr => arr.filter( i => arr.indexOf( i ) === arr.lastIndexOf( i ) );,
"findkey": findkey
const findKey = ( obj, fn ) => Object.keys( obj ).find( key => fn( obj[ key ], key, obj ) );,
"findLast": findLast
const findLast = ( arr, fn ) => arr.filter( fn ).slice( -1 )[ 0 ];,
"findLastIndex": findLastIndex
const findLastIndex = ( arr, fn ) =>
arr
.map( ( val, i ) => [ i, val ] )
.filter( val => fn( val[ 1 ], val[ 0 ], arr ) )
.slice( -1 )[ 0 ][ 0 ];,
"findLastKey": findLastKey
const findLastKey = ( obj, fn ) =>
Object.keys( obj )
.reverse()
.find( key => fn( obj[ key ], key, obj ) );,
"flatten": flatten
const flatten = ( arr, depth = 1 ) =>
depth != 1
? arr.reduce( ( a, v ) => a.concat( Array.isArray( v ) ? flatten( v, depth - 1 ) : v ), [] )
: arr.reduce( ( a, v ) => a.concat( v ), [] );,
"flip": flip
const flip = fn => ( first, ...rest ) => fn( ...rest, first );,
"forEachRight": forEachRight
const forEachRight = ( arr, callback ) =>
arr
.slice( 0 )
.reverse()
.forEach( callback );,
"formatDuration": formatDuration
const formatDuration = ms => {
if ( ms < 0 ) ms = -ms;
const time = {
day: Math.floor( ms / 86400000 ),
hour: Math.floor( ms / 3600000 ) % 24,
minute: Math.floor( ms / 60000 ) % 60,
second: Math.floor( ms / 1000 ) % 60,
millisecond: Math.floor( ms ) % 1000
};
return Object.entries( time )
.filter( val => val[ 1 ] !== 0 )
.map( val => val[ 1 ] + ' ' + ( val[ 1 ] !== 1 ? val[ 0 ] + 's' : val[ 0 ] ) )
.join( ', ' );
};,
"forOwn": forOwn
const forOwn = ( obj, fn ) => Object.keys( obj ).forEach( key => fn( obj[ key ], key, obj ) );,
"forOwnRight": forOwnRight
const forOwnRight = ( obj, fn ) =>
Object.keys( obj )
.reverse()
.forEach( key => fn( obj[ key ], key, obj ) );,
"fromCamelCase": fromCamelCase
const fromCamelCase = ( str, separator = '_' ) =>
str
.replace( /([a-z\\d])([A-Z])/g, '$1' + separator + '$2' )
.replace( /([A-Z]+)([A-Z][a-z\\d]+)/g, '$1' + separator + '$2' )
.toLowerCase();,
"functionName": functionName
const functionName = fn => ( console.debug( fn.name ), fn );,
"functions": functions
const functions = ( obj, inherited = false ) =>
( inherited
? [ ...Object.keys( obj ), ...Object.keys( Object.getPrototypeOf( obj ) ) ]
: Object.keys( obj )
).filter( key => typeof obj[ key ] === 'function' );,
"gcd": gcd
const gcd = ( ...arr ) => {
const _gcd = ( x, y ) => ( !y ? x : gcd( y, x % y ) );
return [ ...arr ].reduce( ( a, b ) => _gcd( a, b ) );
};,
"geometricProgression": geometricProgression
const geometricProgression = ( end, start = 1, step = 2 ) =>
Array.from( { length: Math.floor( Math.log( end / start ) / Math.log( step ) ) + 1 } ).map(
( v, i ) => start * step ** i
);,
"get": get
const get = ( from, ...selectors ) =>
[ ...selectors ].map( s =>
s
.replace( /\\[([^[\\]]*)]/g, '.$1.' )
.split( '.' )
.filter( t => t !== '' )
.reduce( ( prev, cur ) => prev && prev[ cur ], from )
);,
"getDaysDiffBetweenDates": getDaysDiffBetweenDates
const getDaysDiffBetweenDates = ( dateInitial, dateFinal ) =>
( dateFinal - dateInitial ) / ( 1000 * 3600 * 24 );,
"getScrollPosition": getScrollPosition
const getScrollPosition = ( el = window ) => ( {
x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
} );,
"getStyle": getStyle
const getStyle = ( el, ruleName ) => getComputedStyle( el )[ ruleName ];,
"getType": getType
const getType = v =>
v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase();,
"getURLParameters": getURLParameters
const getURLParameters = url =>
( url.match( /([^?=&]+)(=([^&]*))/g ) || [] ).reduce(
( a, v ) => ( ( a[ v.slice( 0, v.indexOf( '=' ) ) ] = v.slice( v.indexOf( '=' ) + 1 ) ), a ),
{}
);,
"groupby": groupby
const groupBy = ( arr, fn ) =>
arr.map( typeof fn === 'function' ? fn : val => val[ fn ] ).reduce( ( acc, val, i ) => {
acc[ val ] = ( acc[ val ] || [] ).concat( arr[ i ] );
return acc;
}, {} );,
"hammingDistance": hammingDistance
const hammingDistance = ( num1, num2 ) => ( ( num1 ^ num2 ).toString( 2 ).match( /1/g ) || '' ).length;,
"hasClass": hasClass
const hasClass = ( el, className ) => el.classList.contains( className );,
"hasFlags": hasFlags
const hasFlags = ( ...flags ) =>
flags.every( flag => process.argv.includes( /^-{1,2}/.test( flag ) ? flag : '--' + flag ) );,
"hashBrowser": hashBrowser
const hashBrowser = val =>
crypto.subtle.digest( 'SHA-256', new TextEncoder( 'utf-8' ).encode( val ) ).then( h => {
let hexes = [],
view = new DataView( h );
for ( let i = 0; i < view.byteLength; i += 4 )
hexes.push( ( '00000000' + view.getUint32( i ).toString( 16 ) ).slice( -8 ) );
return hexes.join( '' );
} );,
"hashNode": hashNode
const crypto = require( 'crypto' );
const hashNode = val =>
new Promise( resolve =>
setTimeout(
() =>
resolve(
crypto
.createHash( 'sha256' )
.update( val )
.digest( 'hex' )
),
0
)
);,
"head": head
const head = arr => arr[ 0 ];,
"hexToRGB": hexToRGB
const hexToRGB = hex => {
let alpha = false,
h = hex.slice( hex.startsWith( '#' ) ? 1 : 0 );
if ( h.length === 3 ) h = [ ...h ].map( x => x + x ).join( '' );
else if ( h.length === 8 ) alpha = true;
h = parseInt( h, 16 );
return (
'rgb' +
( alpha ? 'a' : '' ) +
'(' +
( h >>> ( alpha ? 24 : 16 ) ) +
', ' +
( ( h & ( alpha ? 0x00ff0000 : 0x00ff00 ) ) >>> ( alpha ? 16 : 8 ) ) +
', ' +
( ( h & ( alpha ? 0x0000ff00 : 0x0000ff ) ) >>> ( alpha ? 8 : 0 ) ) +
( alpha ? `, ${ h & 0x000000ff }` : '' ) +
')'
);
};,
"hide": hide
const hide = ( ...el ) => [ ...el ].forEach( e => ( e.style.display = 'none' ) );,
"httpGet": httpGet
const httpGet = ( url, callback, err = console.error ) => {
const request = new XMLHttpRequest();
request.open( 'GET', url, true );
request.onload = () => callback( request.responseText );
request.onerror = () => err( request );
request.send();
};,
"httpPost": httpPost
const httpPost = ( url, data, callback, err = console.error ) => {
const request = new XMLHttpRequest();
request.open( 'POST', url, true );
request.setRequestHeader( 'Content-type', 'application/json; charset=utf-8' );
request.onload = () => callback( request.responseText );
request.onerror = () => err( request );
request.send( data );
};,
"httpsRedirect": httpsRedirect
const httpsRedirect = () => {
if ( location.protocol !== 'https:' ) location.replace( 'https://' + location.href.split( '//' )[ 1 ] );
};,
"indexOfAll": indexOfAll
const indexOfAll = ( arr, val ) => {
const indices = [];
arr.forEach( ( el, i ) => el === val && indices.push( i ) );
return indices;
};,
"initial": initial
const initial = arr => arr.slice( 0, -1 );,
"initializeArrayWithRange": initializeArrayWithRange
const initializeArrayWithRange = ( end, start = 0, step = 1 ) =>
Array.from( { length: Math.ceil( ( end + 1 - start ) / step ) } ).map( ( v, i ) => i * step + start );,
"initializeArrayWithRangeRight": initializeArrayWithRangeRight
const initializeArrayWithRangeRight = ( end, start = 0, step = 1 ) =>
Array.from( { length: Math.ceil( ( end + 1 - start ) / step ) } ).map(
( v, i, arr ) => ( arr.length - i - 1 ) * step + start
);,
"initializeArrayWithValues": initializeArrayWithValues
const initializeArrayWithValues = ( n, val = 0 ) => Array( n ).fill( val );,
"inRange": inRange
const inRange = ( n, start, end = null ) => {
if ( end && start > end ) end = [ start, ( start = end ) ][ 0 ];
return end == null ? n >= 0 && n < start : n >= start && n < end;
};,
"intersection": function intersection( a, b ) {
const s = new Set( b );
return a.filter( x => s.has( x ) );
},
"intersectionBy": function intersectionBy( a, b, fn ) {
const s = new Set( b.map( x => fn( x ) ) );
return a.filter( x => s.has( fn( x ) ) );
},
"intersectionWith": function intersectionWith( a, b, comp ) {
return a.filter( x => b.findIndex( y => comp( x, y ) ) !== -1 );
},
"invertKeyValues": function invertKeyValues( obj, fn ) {
return Object.keys( obj ).reduce( ( acc, key ) => {
const val = fn ? fn( obj[ key ] ) : obj[ key ];
acc[ val ] = acc[ val ] || [];
acc[ val ].push( key );
return acc;
}, {} );
},
"is": function is( type, val ) {
return val instanceof type;
},
"isAbsoluteURL": function isAbsoluteURL( str ) {
return /^[a-z][a-z0-9+.-]*:/.test( str );
},
"isArrayLike": function isArrayLike( val ) {
try {
return [ ...val ], true;
} catch ( e ) {
return false;
}
},
"isBoolean": function isBoolean( val ) {
return typeof val === 'boolean';
},
"isDivisible": isDivisible
const isDivisible = ( dividend, divisor ) => dividend % divisor === 0;,
"isEmpty": isEmpty
const isEmpty = val => val == null || !( Object.keys( val ) || val ).length;,
"isEven": function isEven( num ) {
return num % 2 === 0;
},
"isFunction": function isFunction( val ) {
return typeof val === 'function';
},
"isLowerCase": isLowerCase
const isLowerCase = str => str === str.toLowerCase();,
"isNil": isNil
const isNil = val => val === undefined || val === null;,
"isNull": isNull
const isNull = val => val === null;,
"isNumber": isNumber
const isNumber = val => typeof val === 'number';,
"isObject": isObject
const isObject = obj => obj === Object( obj );,
"isObjectLike": isObjectLike
```js
const isObjectLike = val => val !== null && typeof val === 'object';,
"isPlainObject":isPlainObject
const isPlainObject = val => !!val && typeof val === 'object' && val.constructor === Object;,
"isPrime":isPrime
const isPrime = num => {
const boundary = Math.floor(Math.sqrt(num));
for (var i = 2; i <= boundary; i++) if (num % i == 0)
return false;
return num >= 2;
};,
"isPrimitive":isPrimitive
const isPrimitive = val => !['object', 'function'].includes(typeof val) || val === null;,
"isPromiseLike":isPromiseLike
const isPromiseLike = obj =>
obj !== null &&
(typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function';,
"isSorted":isSorted
const isSorted = arr => {
const direction = arr[0] > arr[1] ? -1 : 1;
for (let [i, val] of arr.entries())
if (i === arr.length - 1)
return direction;
else if ((val - arr[i + 1]) * direction > 0)
return 0;
};,
"isString":isString
const isString = val => typeof val === 'string';,
"isSymbol":isSymbol
const isSymbol = val => typeof val === 'symbol';,
"isTravisCI":isTravisCI
const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env;,
"isUndefined":isUndefined
const isUndefined = val => val === undefined;,
"isUpperCase":isUpperCase
const isUpperCase = str => str === str.toUpperCase();,
"isValidJSON":isValidJSON
const isValidJSON = obj => {
try {
JSON.parse(obj);
return true;
} catch (e) {
return false;
}
};,
"join":join
const join = (arr, separator = ',', end = separator) =>
arr.reduce(
(acc, val, i) =>
i == arr.length - 2
? acc + val + end
: i == arr.length - 1 ? acc + val : acc + val + separator,
''
);,
"JSONToFile":JSONToFile
const fs = require('fs');
const JSONToFile = (obj, filename) =>
fs.writeFile(`\\$\\{ filename\\ }.json`, JSON.stringify(obj, null, 2));,
"last":last
const last = arr => arr[arr.length - 1];,
"lcm":lcm
const lcm = (...arr) => {
const gcd = (x, y) => (!y ? x : gcd(y, x % y));
const _lcm = (x, y) => x * y / gcd(x, y);
return [...arr].reduce((a, b) => _lcm(a, b));
};,
"longestItem":longestItem
const longestItem = (...vals) => [...vals].sort((a, b) => b.length - a.length)[0];,
"lowercaseKeys":lowercaseKeys
const lowercaseKeys = obj =>
Object.keys(obj).reduce((acc, key) => {
acc[key.toLowerCase()] = obj[key];
return acc;
}, {});,
"luhnCheck":luhnCheck
const luhnCheck = num => {
let arr = (num + '')
.split('')
.reverse()
.map(x => parseInt(x));
let lastDigit = arr.splice(0, 1)[0];
let sum = arr.reduce((acc, val, i) => (i % 2 !== 0 ? acc + val : acc + (val * 2) % 9 || 9), 0);
sum += lastDigit;
return ",
"mapKeys":mapKeys
const mapKeys = (obj, fn) =>
Object.keys(obj).reduce((acc, k) => {
acc[fn(obj[k], k, obj)] = obj[k];
return acc;
}, {});,
"mapObject":mapObject
const mapObject = (arr, fn) =>
(a => (
(a = [arr, arr.map(fn)]), a[0].reduce((acc, val, ind) => ((acc[val] = a[1][ind]), acc), {})
))();,
"mapValues":mapValues
const mapValues = (obj, fn) =>
Object.keys(obj).reduce((acc, k) => {
acc[k] = fn(obj[k], k, obj);
return acc;
}, {});,
"mask":mask
const mask = (cc, num = 4, mask = '*') =>
('' + cc).slice(0, -num).replace(/./g, mask) + ('' + cc).slice(-num);,
"matches":matches
const matches = (obj, source) =>
Object.keys(source).every(key => obj.hasOwnProperty(key) && obj[key] === source[key]);,
"matchesWith":matchesWith
const matchesWith = (obj, source, fn) =>
Object.keys(source).every(
key =>
obj.hasOwnProperty(key) && fn
? fn(obj[key], source[key], key, obj, source)
: obj[key] == source[key]
);,
"maxBy":maxBy
const maxBy = (arr, fn) => Math.max(...arr.map(typeof fn === 'function' ? fn : val => val[fn]));,
"maxN":maxN
const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n);,
"median":median
const median = arr => {
const mid = Math.floor(arr.length / 2),
nums = [...arr].sort((a, b) => a - b);
return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
};,
"memoize":memoize
const memoize = fn => {
const cache = new Map();
const cached = function(val) {
return cache.has(val) ? cache.get(val) : cache.set(val, fn.call(this, val)) && cache.get(val);
};
cached.cache = cache;
return cached;
};,
"merge":merge
const merge = (...objs) =>
[...objs].reduce(
(acc, obj) =>
Object.keys(obj).reduce((a, k) => {
acc[k] = acc.hasOwnProperty(k) ? [].concat(acc[k]).concat(obj[k]) : obj[k];
return acc;
}, {}),
{}
);,
"minBy":minBy
const minBy = (arr, fn) => Math.min(...arr.map(typeof fn === 'function' ? fn : val => val[fn]));,
"minN":minN
const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n);,
"negate":negate
const negate = func => (...args) => !func(...args);,
"nthArg":nthArg
const nthArg = n => (...args) => args.slice(n)[0];,
"nthElement":nthElement
const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0];,
"objectFromPairs":objectFromPairs
const objectFromPairs = arr => arr.reduce((a, v) => ((a[v[0]] = v[1]), a), {});,
"objectToPairs":objectToPairs
const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]);,
"observeMutations":observeMutations
const observeMutations = (element, callback, options) => {
const observer = new MutationObserver(mutations => mutations.forEach(m => callback(m)));
observer.observe(
element,
Object.assign(
{
childList: true,
attributes: true,
attributeOldValue: true,
characterData: true,
characterDataOldValue: true,
subtree: true
},
options
)
);
return observer;
};,
"off":off
const off = (el, evt, fn, opts = false) => el.removeEventListener(evt, fn, opts);,
"omit":omit
const omit = (obj, arr) =>
Object.keys(obj)
.filter(k => !arr.includes(k))
.reduce((acc, key) => ((acc[key] = obj[key]), acc), {});,
"omitBy":omitBy
const omitBy = (obj, fn) =>
Object.keys(obj)
.filter(k => !fn(obj[k], k))
.reduce((acc, key) => ((acc[key] = obj[key]), acc), {});,
"on":on
const on = (el, evt, fn, opts = {}) => {
const delegatorFn = e => e.target.matches(opts.target) && fn.call(e.target, e);
el.addEventListener(evt, opts.target ? delegatorFn : fn, opts.options || false);
if (opts.target)
return delegatorFn;
};,
"once":once
const once = fn => {
let called = false;
return function(...args) {
if (called)
return ;
called = true;
return fn.apply(this, args);
};
};,
"onUserInputChange":onUserInputChange
const onUserInputChange = callback => {
let type = 'mouse',
lastTime = 0;
const mousemoveHandler = () => {
const now = performance.now();
if (now - lastTime < 20)
(type = 'mouse'), callback(type), document.removeEventListener('mousemove', mousemoveHandler);
lastTime = now;
};
document.addEventListener('touchstart', () => {
if (type === 'touch')
return ;
(type = 'touch'), callback(type), document.addEventListener('mousemove', mousemoveHandler);
});
};,
"orderBy":orderBy
const orderBy = (arr, props, orders) =>
[...arr].sort((a, b) =>
props.reduce((acc, prop, i) => {
if (acc === 0) {
const [p1, p2] = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]];
acc = p1 > p2 ? 1 : p1 < p2 ? -1 : 0;
}
return acc;
}, 0)
);,
"over":over
const over = (...fns) => (...args) => fns.map(fn => fn.apply(null, args));,
"palindrome":palindrome
const palindrome = str => {
const s = str.toLowerCase().replace(/[\\W_]/g, '');
return (
s ===
s
.split('')
.reverse()
.join('')
);
};,
"parseCookie":parseCookie
const parseCookie = str =>
str
.split(';')
.map(v => v.split('='))
.reduce((acc, v) => {
acc[decodeURIComponent(v[0].trim())] = decodeURIComponent(v[1].trim());
return acc;
}, {});,
"partial":partial
const partial = (fn, ...partials) => (...args) => fn(...partials, ...args);,
"partailRight":partailRight
const partialRight = (fn, ...partials) => (...args) => fn(...args, ...partials);,
"partition":partition
const partition = (arr, fn) =>
arr.reduce(
(acc, val, i, arr) => {
acc[fn(val, i, arr) ? 0 : 1].push(val);
return acc;
},
[[], []]
);,
"percentile":percentile
const percentile = (arr, val) =>
100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length;,
"pick":pick
const pick = (obj, arr) =>
arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});,
"pickBy":pickBy
const pickBy = (obj, fn) =>
Object.keys(obj)
.filter(k => fn(obj[k], k))
.reduce((acc, key) => ((acc[key] = obj[key]), acc), {});,
"pipeFunctions":pipeFunctions
const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));,
"pluralize":pluralize
const pluralize = (val, word, plural = word + 's') => {
const _pluralize = (num, word, plural = word + 's') =>
[1, -1].includes(Number(num)) ? word : plural;
if (typeof val === 'object')
return (num, word) => _pluralize(num, word, val[word]);
return _pluralize(val, word, plural);
};,
"powerset":powerset
const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]);,
"prettyBytes":prettyBytes
const prettyBytes = (num, precision = 3, addSpace = true) => {
const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
if (Math.abs(num) < 1)
return num + (addSpace ? ' ' : '') + UNITS[0];
const exponent = Math.min(Math.floor(Math.log10(num < 0 ? -num : num) / 3), UNITS.length - 1);
const n = Number(((num < 0 ? -num : num) / 1000 ** exponent).toPrecision(precision));
return (num < 0 ? '-' : '') + n + (addSpace ? ' ' : '') + UNITS[exponent];
};,
"primes":primes
const primes = num => {
let arr = Array.from({ length: num - 1 }).map((x, i) => i + 2),
sqroot = Math.floor(Math.sqrt(num)),
numsTillSqroot = Array.from({ length: sqroot - 1 }).map((x, i) => i + 2);
numsTillSqroot.forEach(x => (arr = arr.filter(y => y % x !== 0 || y == x)));
return arr;
};,
"promisify":promisify
const promisify = func => (...args) =>
new Promise((resolve, reject) =>
func(...args, (err, result) => (err ? reject(err) : resolve(result)))
);,
"pull":pull
const pull = (arr, ...args) => {
let argState = Array.isArray(args[0]) ? args[0] : args;
let pulled = arr.filter((v, i) => !argState.includes(v));
arr.length = 0;
pulled.forEach(v => arr.push(v));
};,
"pullAtIndex":pullAtIndex
const pullAtIndex = (arr, pullArr) => {
let removed = [];
let pulled = arr
.map((v, i) => (pullArr.includes(i) ? removed.push(v) : v))
.filter((v, i) => !pullArr.includes(i));
arr.length = 0;
pulled.forEach(v => arr.push(v));
return removed;
};,
"pullAtValue":pullAtValue
const pullAtValue = (arr, pullArr) => {
let removed = [],
pushToRemove = arr.forEach((v, i) => (pullArr.includes(v) ? removed.push(v) : v)),
mutateTo = arr.filter((v, i) => !pullArr.includes(v));
arr.length = 0;
mutateTo.forEach(v => arr.push(v));
return removed;
};,
"randomHexColorCode":randomHexColorCode
const randomHexColorCode = () => {
let n = ((Math.random() * 0xfffff) | 0).toString(16);
return '#' + (n.length !== 6 ? ((Math.random() * 0xf) | 0).toString(16) + n : n);
};,
"randomIntArrayInRange":randomIntArrayInRange
const randomIntArrayInRange = (min, max, n = 1) =>
Array.from({ length: n }, () => Math.floor(Math.random() * (max - min + 1)) + min);,
"randomIntegerInRange":randomIntegerInRange
const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;,
"randomNumberInRange":randomNumberInRange
const randomNumberInRange = (min, max) => Math.random() * (max - min) + min;,
"readFileLines":readFileLines
const fs = require('fs');
const readFileLines = filename =>
fs
.readFileSync(filename)
.toString('UTF8')
.split('
');,
"redirect":redirect
const redirect = (url, asLink = true) =>
asLink ? (window.location.href = url) : window.location.replace(url);,
"reducedFilter":reducedFilter
const reducedFilter = (data, keys, fn) =>
data.filter(fn).map(el =>
keys.reduce((acc, key) => {
acc[key] = el[key];
return acc;
}, {})
);,
"reduceSuccessive":reduceSuccessive
const reduceSuccessive = (arr, fn, acc) =>
arr.reduce((res, val, i, arr) => (res.push(fn(res.slice(-1)[0], val, i, arr)), res), [acc]);,
"reduceWhich":reduceWhich
const reduceWhich = (arr, comparator = (a, b) => a - b) =>
arr.reduce((a, b) => (comparator(a, b) >= 0 ? b : a));,
"remove":remove
const remove = (arr, func) =>
Array.isArray(arr)
? arr.filter(func).reduce((acc, val) => {
arr.splice(arr.indexOf(val), 1);
return acc.concat(val);
}, [])
: [];,
"removeNonASCII":removeNonASCII
const removeNonASCII = str => str.replace(/[^\\x20-\\x7E]/g, '');,
"reverseString":reverseString
const reverseString = str => [...str].reverse().join('');,
"RGBToHex":RGBToHex
const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');,
"round":round
const round = (n, decimals = 0) => Number(`${ Math.round( `${ n }e${ decimals }` ) } e - ${ decimals } `);,
"runAsync":runAsync
const runAsync = fn => {
const blob = `var fn = ${ fn.toString()}; postMessage( fn() ); `;
const worker = new Worker(
URL.createObjectURL(new Blob([blob]), {
type: 'application/javascript; charset=utf-8'
})
);
return new Promise((res, rej) => {
worker.onmessage = ({ data }) => {
res(data), worker.terminate();
};
worker.onerror = err => {
rej(err), worker.terminate();
};
});
};,
"runPromisesInSeries":runPromisesInSeries
const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());,
"sample":sample
const sample = arr => arr[Math.floor(Math.random() * arr.length)];,
"sampleSize":sampleSize
const sampleSize = ([...arr], n = 1) => {
let m = arr.length;
while (m) {
const i = Math.floor(Math.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr.slice(0, n);
};,
"scrollToTop":scrollToTop
const scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
};,
"sdbm":sdbm
const sdbm = str => {
let arr = str.split('');
return arr.reduce(
(hashCode, currentVal) =>
(hashCode = currentVal.charCodeAt(0) + (hashCode << 6) + (hashCode << 16) - hashCode),
0
);
};,
"serializeCookie":serializeCookie
const serializeCookie = (name, val) => `${ encodeURIComponent( name ) }=${ encodeURIComponent( val ) } `;,
"setStyle":setStyle
const setStyle = (el, ruleName, val) => (el.style[ruleName] = val);,
"shallowClone":shallowClone
```js
const shallowClone = obj => Object.assign( {}, obj );,
"show": show
const show = ( ...el ) => [ ...el ].forEach( e => ( e.style.display = '' ) );,
"shuffle": shuffle
const shuffle = ( [ ...arr ] ) => {
let m = arr.length;
while ( m ) {
const i = Math.floor( Math.random() * m-- );
[ arr[ m ], arr[ i ] ] = [ arr[ i ], arr[ m ] ];
}
return arr;
};,
"similarity": similarity
const similarity = ( arr, values ) => arr.filter( v => values.includes( v ) );,
"size": size
const size = val =>
Array.isArray( val )
? val.length
: val && typeof val === 'object'
? val.size || val.length || Object.keys( val ).length
: typeof val === 'string' ? new Blob( [ val ] ).size : 0;,
"sleep": sleep
const sleep = ms => new Promise( resolve => setTimeout( resolve, ms ) );,
"sortCharactersInString": sortCharactersInString
const sortCharactersInString = str => [ ...str ].sort( ( a, b ) => a.localeCompare( b ) ).join( '' );,
"sortedIndex": sortedIndex
const sortedIndex = ( arr, n ) => {
const isDescending = arr[ 0 ] > arr[ arr.length - 1 ];
const index = arr.findIndex( el => ( isDescending ? n >= el : n <= el ) );
return index === -1 ? arr.length : index;
};,
"sortedIndexBy": sortedIndexBy
const sortedIndexBy = ( arr, n, fn ) => {
const isDescending = fn( arr[ 0 ] ) > fn( arr[ arr.length - 1 ] );
const val = fn( n );
const index = arr.findIndex( el => ( isDescending ? val >= fn( el ) : val <= fn( el ) ) );
return index === -1 ? arr.length : index;
};,
"sortedLastIndex": sortedLastIndex
const sortedLastIndex = ( arr, n ) => {
const isDescending = arr[ 0 ] > arr[ arr.length - 1 ];
const index = arr
.map( ( val, i ) => [ i, val ] )
.reverse()
.findIndex( el => ( isDescending ? n <= el[ 1 ] : n >= el[ 1 ] ) );
return index === -1 ? 0 : arr.length - index - 1;
};,
"sortedLastIndexBy": sortedLastIndexBy
const sortedLastIndexBy = ( arr, n, fn ) => {
const isDescending = fn( arr[ 0 ] ) > fn( arr[ arr.length - 1 ] );
const val = fn( n );
const index = arr
.map( ( val, i ) => [ i, fn( val ) ] )
.reverse()
.findIndex( el => ( isDescending ? val <= el[ 1 ] : val >= el[ 1 ] ) );
return index === -1 ? 0 : arr.length - index;
};,
"splitLines": splitLines
const splitLines = str => str.split( /\r?
/);,
"spreadOver": spreadOver
const spreadOver = fn => argsArr => fn( ...argsArr );,
"standardDeviation": standardDeviation
const standardDeviation = ( arr, usePopulation = false ) => {
const mean = arr.reduce( ( acc, val ) => acc + val, 0 ) / arr.length;
return Math.sqrt(
arr.reduce( ( acc, val ) => acc.concat( ( val - mean ) ** 2 ), [] ).reduce( ( acc, val ) => acc + val, 0 ) /
( arr.length - ( usePopulation ? 0 : 1 ) )
);
};,
"stripHTMLTags": stripHTMLTags
const stripHTMLTags = str => str.replace( /<[^>]*>/g, '' );,
"sum": sum
const sum = ( ...arr ) => [ ...arr ].reduce( ( acc, val ) => acc + val, 0 );,
"sumBy": sumBy
const sumBy = ( arr, fn ) =>
arr.map( typeof fn === 'function' ? fn : val => val[ fn ] ).reduce( ( acc, val ) => acc + val, 0 );,
"sumPower": sumPower
const sumPower = ( end, power = 2, start = 1 ) =>
Array( end + 1 - start )
.fill( 0 )
.map( ( x, i ) => ( i + start ) ** power )
.reduce( ( a, b ) => a + b, 0 );,
"symmetricDifference": symmetricDifference
const symmetricDifference = ( a, b ) => {
const sA = new Set( a ),
sB = new Set( b );
return [ ...a.filter( x => !sB.has( x ) ), ...b.filter( x => !sA.has( x ) ) ];
};,
"symmetricDifferenceBy": symmetricDifferenceBy
const symmetricDifferenceBy = ( a, b, fn ) => {
const sA = new Set( a.map( v => fn( v ) ) ),
sB = new Set( b.map( v => fn( v ) ) );
return [ ...a.filter( x => !sB.has( fn( x ) ) ), ...b.filter( x => !sA.has( fn( x ) ) ) ];
};,
"symmetricDifferenceWith": symmetricDifferenceWith
const symmetricDifferenceWith = ( arr, val, comp ) => [
...arr.filter( a => val.findIndex( b => comp( a, b ) ) === -1 ),
...val.filter( a => arr.findIndex( b => comp( a, b ) ) === -1 )
];,
"tail": tail
const tail = arr => ( arr.length > 1 ? arr.slice( 1 ) : arr );,
"take": take
const take = ( arr, n = 1 ) => arr.slice( 0, n );,
"takeRight": takeRight
const takeRight = ( arr, n = 1 ) => arr.slice( arr.length - n, arr.length );,
"takeWhile": takeWhile
const takeWhile = ( arr, func ) => {
for ( let i of arr.keys() ) if ( func( arr[ i ] ) )
return arr.slice( 0, i );
return arr;
};,
"times": times
const times = ( n, fn, context = undefined ) => {
let i = 0;
while ( fn.call( context, i ) !== false && ++i < n ) { }
};,
"timeTaken": timeTaken
const timeTaken = callback => {
console.time( 'timeTaken' );
const r = callback();
console.timeEnd( 'timeTaken' );
return r;
};,
"toCamelCase": toCamelCase
const toCamelCase = str => {
let s =
str &&
str
.match( /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g )
.map( x => x.slice( 0, 1 ).toUpperCase() + x.slice( 1 ).toLowerCase() )
.join( '' );
return s.slice( 0, 1 ).toLowerCase() + s.slice( 1 );
};,
"toDecimalMark": toDecimalMark
const toDecimalMark = num => num.toLocaleString( 'en-US' );,
"toggleClass": toggleClass
const toggleClass = ( el, className ) => el.classList.toggle( className );,
"toKebabCase": toKebabCase
const toKebabCase = str =>
str &&
str
.match( /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g )
.map( x => x.toLowerCase() )
.join( '-' );,
"tomorrow": tomorrow
const tomorrow = () => {
let t = new Date();
t.setDate( t.getDate() + 1 );
return `${ t.getFullYear() }-${ String( t.getMonth() + 1 ).padStart( 2, '0' ) }-${ String(
t.getDate()
).padStart( 2, '0' ) }`;
};,
"toOrdinalSuffix": toOrdinalSuffix
const toOrdinalSuffix = num => {
const int = parseInt( num ),
digits = [ int % 10, int % 100 ],
ordinals = [ 'st', 'nd', 'rd', 'th' ],
oPattern = [ 1, 2, 3, 4 ],
tPattern = [ 11, 12, 13, 14, 15, 16, 17, 18, 19 ];
return oPattern.includes( digits[ 0 ] ) && !tPattern.includes( digits[ 1 ] )
? int + ordinals[ digits[ 0 ] - 1 ]
: int + ordinals[ 3 ];
};,
"toSafeInteger": toSafeInteger
const toSafeInteger = num =>
Math.round( Math.max( Math.min( num, Number.MAX_SAFE_INTEGER ), Number.MIN_SAFE_INTEGER ) );,
"toSnakeCase": toSnakeCase
const toSnakeCase = str =>
str &&
str
.match( /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g )
.map( x => x.toLowerCase() )
.join( '_' );,
"transform": transform
const transform = ( obj, fn, acc ) => Object.keys( obj ).reduce( ( a, k ) => fn( a, obj[ k ], k, obj ), acc );,
"truncateString": truncateString
const truncateString = ( str, num ) =>
str.length > num ? str.slice( 0, num > 3 ? num - 3 : num ) + '...' : str;,
"truthCheckCollection": truthCheckCollection
const truthCheckCollection = ( collection, pre ) => collection.every( obj => obj[ pre ] );,
"unary": unary
const unary = fn => val => fn( val );,
"unescapeHTML": unescapeHTML
const unescapeHTML = str =>
str.replace(
/&amp;|&lt;|&gt;|&#39;|&quot;/g,
tag =>
( {
'&amp;': '&',
'&lt;': '<',
'&gt;': '>',
'&#39;': \"'\",
'&quot;': '\"'
}[ tag ] || tag )
);,
"unfold": unfold
const unfold = ( fn, seed ) => {
let result = [],
val = [ null, seed ];
while ( ( val = fn( val[ 1 ] ) ) ) result.push( val[ 0 ] );
return result;
};,
"union": union
const union = ( a, b ) => Array.from( new Set( [ ...a, ...b ] ) );,
"unionBy": unionBy
const unionBy = ( a, b, fn ) => {
const s = new Set( a.map( v => fn( v ) ) );
return Array.from( new Set( [ ...a, ...b.filter( x => !s.has( fn( x ) ) ) ] ) );
};,
"unionWith": unionWith
const unionWith = ( a, b, comp ) =>
Array.from( new Set( [ ...a, ...b.filter( x => a.findIndex( y => comp( x, y ) ) === -1 ) ] ) );,
"uniqueElements": uniqueElements
const uniqueElements = arr => [ ...new Set( arr ) ];,
"untildify": untildify
const untildify = str => str.replace( /^~(\\$|/ |\\ ) /, `${ require( 'os' ).homedir() }$1`);,
"unzip": unzip
const unzip = arr =>
arr.reduce(
( acc, val ) => ( val.forEach( ( v, i ) => acc[ i ].push( v ) ), acc ),
Array.from( {
length: Math.max( ...arr.map( x => x.length ) )
} ).map( x => [] )
);,
"unzipWith": unzipWith
const unzipWith = ( arr, fn ) =>
arr
.reduce(
( acc, val ) => ( val.forEach( ( v, i ) => acc[ i ].push( v ) ), acc ),
Array.from( {
length: Math.max( ...arr.map( x => x.length ) )
} ).map( x => [] )
)
.map( val => fn( ...val ) );,
"URLJoin": URLJoin
const URLJoin = ( ...args ) =>
args
.join( '/' )
.replace( /[/]+/g, '/' )
.replace( /^(.+):/ /, '$1://' )
.replace( /^file:/, 'file:/' )
.replace(//(\\?|&|#[^!])/g, '$1')
.replace( /\\?/g, '&' )
.replace( '&', '?' );,
"UUIDGeneratorBrowser": UUIDGeneratorBrowser
const UUIDGeneratorBrowser = () =>
( [ 1e7 ] + -1e3 + -4e3 + -8e3 + -1e11 ).replace( /[018]/g, c =>
( c ^ ( crypto.getRandomValues( new Uint8Array( 1 ) )[ 0 ] & ( 15 >> ( c / 4 ) ) ) ).toString( 16 )
);,
"UUIDGeneratorNode": UUIDGeneratorNode
const crypto = require( 'crypto' );
const UUIDGeneratorNode = () =>
( [ 1e7 ] + -1e3 + -4e3 + -8e3 + -1e11 ).replace( /[018]/g, c =>
( c ^ ( crypto.randomBytes( 1 )[ 0 ] & ( 15 >> ( c / 4 ) ) ) ).toString( 16 )
);,
"validateNumber": validateNumber
const validateNumber = n => !isNaN( parseFloat( n ) ) && isFinite( n ) && Number( n ) == n;,
"without": without
const without = ( arr, ...args ) => arr.filter( v => !args.includes( v ) );,
"words": words
const words = ( str, pattern = /[^a-zA-Z-]+/ ) => str.split( pattern ).filter( Boolean );,
"xProd": xProd
const xProd = ( a, b ) => a.reduce( ( acc, x ) => acc.concat( b.map( y => [ x, y ] ) ), [] );,
"yesNo": yesNo
const yesNo = ( val, def = false ) =>
/^(y|yes)\\$/i.test( val ) ? true : /^(n|no)\\$/i.test( val ) ? false : def;,
"zip": zip
const zip = ( ...arrays ) => {
const maxLength = Math.max( ...arrays.map( x => x.length ) );
return Array.from( { length: maxLength } ).map( ( _, i ) => {
return Array.from( { length: arrays.length }, ( _, k ) => arrays[ k ][ i ] );
} );
};,
"zipObject": zipObject
const zipObject = ( props, values ) =>
props.reduce( ( obj, prop, index ) => ( ( obj[ prop ] = values[ index ] ), obj ), {} );,
"zipWith": zipWith
const zipWith = ( ...arrays ) => {
const length = arrays.length;
let fn = length > 1 ? arrays[ length - 1 ] : undefined;
fn = typeof fn == 'function' ? ( arrays.pop(), fn ) : undefined;
const maxLength = Math.max( ...arrays.map( x => x.length ) );
const result = Array.from( { length: maxLength } ).map( ( _, i ) => {
return Array.from( { length: arrays.length }, ( _, k ) => arrays[ k ][ i ] );
} );
return fn ? result.map( arr => fn( ...arr ) ) : result;
};,
This file has been truncated, but you can view the full file.
<!DOCTYPE html>
<html>
<head>
<title>no title</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.markdown-preview{width:100%;height:100%;box-sizing:border-box}.markdown-preview .pagebreak,.markdown-preview .newpage{page-break-before:always}.markdown-preview pre.line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}.markdown-preview pre.line-numbers>code{position:relative}.markdown-preview pre.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:1em;font-size:100%;left:0;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.markdown-preview pre.line-numbers .line-numbers-rows>span{pointer-events:none;display:block;counter-increment:linenumber}.markdown-preview pre.line-numbers .line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}.markdown-preview .mathjax-exps .MathJax_Display{text-align:center !important}.markdown-preview:not([for="preview"]) .code-chunk .btn-group{display:none}.markdown-preview:not([for="preview"]) .code-chunk .status{display:none}.markdown-preview:not([for="preview"]) .code-chunk .output-div{margin-bottom:16px}.scrollbar-style::-webkit-scrollbar{width:8px}.scrollbar-style::-webkit-scrollbar-track{border-radius:10px;background-color:transparent}.scrollbar-style::-webkit-scrollbar-thumb{border-radius:5px;background-color:rgba(150,150,150,0.66);border:4px solid rgba(150,150,150,0.66);background-clip:content-box}html body[for="html-export"]:not([data-presentation-mode]){position:relative;width:100%;height:100%;top:0;left:0;margin:0;padding:0;overflow:auto}html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview{position:relative;top:0}@media screen and (min-width:914px){html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview{padding:2em calc(50% - 457px + 2em)}}@media screen and (max-width:914px){html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview{padding:2em}}@media screen and (max-width:450px){html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview{font-size:14px !important;padding:1em}}@media print{html body[for="html-export"]:not([data-presentation-mode]) #sidebar-toc-btn{display:none}}html body[for="html-export"]:not([data-presentation-mode]) #sidebar-toc-btn{position:fixed;bottom:8px;left:8px;font-size:28px;cursor:pointer;color:inherit;z-index:99;width:32px;text-align:center;opacity:.4}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] #sidebar-toc-btn{opacity:1}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc{position:fixed;top:0;left:0;width:300px;height:100%;padding:32px 0 48px 0;font-size:14px;box-shadow:0 0 4px rgba(150,150,150,0.33);box-sizing:border-box;overflow:auto;background-color:inherit}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar{width:8px}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar-track{border-radius:10px;background-color:transparent}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar-thumb{border-radius:5px;background-color:rgba(150,150,150,0.66);border:4px solid rgba(150,150,150,0.66);background-clip:content-box}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc a{text-decoration:none}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc ul{padding:0 1.6em;margin-top:.8em}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc li{margin-bottom:.8em}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc ul{list-style-type:none}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{left:300px;width:calc(100% - 300px);padding:2em calc(50% - 457px - 150px);margin:0;box-sizing:border-box}@media screen and (max-width:1274px){html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{padding:2em}}@media screen and (max-width:450px){html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{width:100%}}html body[for="html-export"]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .markdown-preview{left:50%;transform:translateX(-50%)}html body[for="html-export"]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .md-sidebar-toc{display:none}/**
* prism.js Github theme based on GitHub's theme.
* @author Sam Clarke
*/
code[class*="language-"],
pre[class*="language-"] {
color: #333;
background: none;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.4;
-moz-tab-size: 8;
-o-tab-size: 8;
tab-size: 8;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
/* Code blocks */
pre[class*="language-"] {
padding: .8em;
overflow: auto;
/* border: 1px solid #ddd; */
border-radius: 3px;
/* background: #fff; */
background: #f5f5f5;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
background: #f5f5f5;
}
.token.comment,
.token.blockquote {
color: #969896;
}
.token.cdata {
color: #183691;
}
.token.doctype,
.token.punctuation,
.token.variable,
.token.macro.property {
color: #333;
}
.token.operator,
.token.important,
.token.keyword,
.token.rule,
.token.builtin {
color: #a71d5d;
}
.token.string,
.token.url,
.token.regex,
.token.attr-value {
color: #183691;
}
.token.property,
.token.number,
.token.boolean,
.token.entity,
.token.atrule,
.token.constant,
.token.symbol,
.token.command,
.token.code {
color: #0086b3;
}
.token.tag,
.token.selector,
.token.prolog {
color: #63a35c;
}
.token.function,
.token.namespace,
.token.pseudo-element,
.token.class,
.token.class-name,
.token.pseudo-class,
.token.id,
.token.url-reference .token.variable,
.token.attr-name {
color: #795da3;
}
.token.entity {
cursor: help;
}
.token.title,
.token.title .token.punctuation {
font-weight: bold;
color: #1d3e81;
}
.token.list {
color: #ed6a43;
}
.token.inserted {
background-color: #eaffea;
color: #55a532;
}
.token.deleted {
background-color: #ffecec;
color: #bd2c00;
}
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
/* JSON */
.language-json .token.property {
color: #183691;
}
.language-markup .token.tag .token.punctuation {
color: #333;
}
/* CSS */
code.language-css,
.language-css .token.function {
color: #0086b3;
}
/* YAML */
.language-yaml .token.atrule {
color: #63a35c;
}
code.language-yaml {
color: #183691;
}
/* Ruby */
.language-ruby .token.function {
color: #333;
}
/* Markdown */
.language-markdown .token.url {
color: #795da3;
}
/* Makefile */
.language-makefile .token.symbol {
color: #795da3;
}
.language-makefile .token.variable {
color: #183691;
}
.language-makefile .token.builtin {
color: #0086b3;
}
/* Bash */
.language-bash .token.keyword {
color: #0086b3;
}
/* highlight */
pre[data-line] {
position: relative;
padding: 1em 0 1em 3em;
}
pre[data-line] .line-highlight-wrapper {
position: absolute;
top: 0;
left: 0;
background-color: transparent;
display: block;
width: 100%;
}
pre[data-line] .line-highlight {
position: absolute;
left: 0;
right: 0;
padding: inherit 0;
margin-top: 1em;
background: hsla(24, 20%, 50%,.08);
background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
pointer-events: none;
line-height: inherit;
white-space: pre;
}
pre[data-line] .line-highlight:before,
pre[data-line] .line-highlight[data-end]:after {
content: attr(data-start);
position: absolute;
top: .4em;
left: .6em;
min-width: 1em;
padding: 0 .5em;
background-color: hsla(24, 20%, 50%,.4);
color: hsl(24, 20%, 95%);
font: bold 65%/1.5 sans-serif;
text-align: center;
vertical-align: .3em;
border-radius: 999px;
text-shadow: none;
box-shadow: 0 1px white;
}
pre[data-line] .line-highlight[data-end]:after {
content: attr(data-end);
top: auto;
bottom: .4em;
}.emoji {
height: 0.8em;
}html body{font-family:"Helvetica Neue",Helvetica,"Segoe UI",Arial,freesans,sans-serif;font-size:16px;line-height:1.6;color:#333;background-color:#fff;overflow:initial;box-sizing:border-box;word-wrap:break-word}html body>:first-child{margin-top:0}html body h1,html body h2,html body h3,html body h4,html body h5,html body h6{line-height:1.2;margin-top:1em;margin-bottom:16px;color:#000}html body h1{font-size:2.25em;font-weight:300;padding-bottom:.3em}html body h2{font-size:1.75em;font-weight:400;padding-bottom:.3em}html body h3{font-size:1.5em;font-weight:500}html body h4{font-size:1.25em;font-weight:600}html body h5{font-size:1.1em;font-weight:600}html body h6{font-size:1em;font-weight:600}html body h1,html body h2,html body h3,html body h4,html body h5{font-weight:600}html body h5{font-size:1em}html body h6{color:#5c5c5c}html body strong{color:#000}html body del{color:#5c5c5c}html body a:not([href]){color:inherit;text-decoration:none}html body a{color:#08c;text-decoration:none}html body a:hover{color:#00a3f5;text-decoration:none}html body img{max-width:100%}html body>p{margin-top:0;margin-bottom:16px;word-wrap:break-word}html body>ul,html body>ol{margin-bottom:16px}html body ul,html body ol{padding-left:2em}html body ul.no-list,html body ol.no-list{padding:0;list-style-type:none}html body ul ul,html body ul ol,html body ol ol,html body ol ul{margin-top:0;margin-bottom:0}html body li{margin-bottom:0}html body li.task-list-item{list-style:none}html body li>p{margin-top:0;margin-bottom:0}html body .task-list-item-checkbox{margin:0 .2em .25em -1.8em;vertical-align:middle}html body .task-list-item-checkbox:hover{cursor:pointer}html body blockquote{margin:16px 0;font-size:inherit;padding:0 15px;color:#5c5c5c;background-color:#f0f0f0;border-left:4px solid #d6d6d6}html body blockquote>:first-child{margin-top:0}html body blockquote>:last-child{margin-bottom:0}html body hr{height:4px;margin:32px 0;background-color:#d6d6d6;border:0 none}html body table{margin:10px 0 15px 0;border-collapse:collapse;border-spacing:0;display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}html body table th{font-weight:bold;color:#000}html body table td,html body table th{border:1px solid #d6d6d6;padding:6px 13px}html body dl{padding:0}html body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:bold}html body dl dd{padding:0 16px;margin-bottom:16px}html body code{font-family:Menlo,Monaco,Consolas,'Courier New',monospace;font-size:.85em !important;color:#000;background-color:#f0f0f0;border-radius:3px;padding:.2em 0}html body code::before,html body code::after{letter-spacing:-0.2em;content:"\00a0"}html body pre>code{padding:0;margin:0;font-size:.85em !important;word-break:normal;white-space:pre;background:transparent;border:0}html body .highlight{margin-bottom:16px}html body .highlight pre,html body pre{padding:1em;overflow:auto;font-size:.85em !important;line-height:1.45;border:#d6d6d6;border-radius:3px}html body .highlight pre{margin-bottom:0;word-break:normal}html body pre code,html body pre tt{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}html body pre code:before,html body pre tt:before,html body pre code:after,html body pre tt:after{content:normal}html body p,html body blockquote,html body ul,html body ol,html body dl,html body pre{margin-top:0;margin-bottom:16px}html body kbd{color:#000;border:1px solid #d6d6d6;border-bottom:2px solid #c7c7c7;padding:2px 4px;background-color:#f0f0f0;border-radius:3px}@media print{html body{background-color:#fff}html body h1,html body h2,html body h3,html body h4,html body h5,html body h6{color:#000;page-break-after:avoid}html body blockquote{color:#5c5c5c}html body pre{page-break-inside:avoid}html body table{display:table}html body img{display:block;max-width:100%;max-height:100%}html body pre,html body code{word-wrap:break-word;white-space:pre}}
html body:before {
content: "Failed to compile `style.less`. NameError: Property '$font-primary' is undefined in input on line 10, column 18:
9 html {
10 font-family: $font-primary;
11 font-size: 110%;
" !important;
padding: 2em !important;
}
.mume.mume { display: none !important; }
</style>
</head>
<body for="html-export">
<div class="mume markdown-preview">
<html><head></head><body><div><p>Converts a comma-separated values (CSV) string to a 2D array.</p>
<ul>
<li>Use <code>Array.prototype.slice()</code> and <code>Array.prototype.indexOf(&apos;\n&apos;)</code> to remove the first row (title row) if <code>omitFirstRow</code> is <code>true</code>.</li>
<li>Use <code>String.prototype.split(&apos;\n&apos;)</code> to create a string for each row, then <code>String.prototype.split(delimiter)</code> to separate the values in each row.</li>
<li>Omit the second argument, <code>delimiter</code>, to use a default delimiter of <code>&apos;,&apos;</code>.</li>
<li>Omit the third argument, <code>omitFirstRow</code>, to include the first row (title row) of the CSV string.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> CSVToArray <span class="token operator">=</span> <span class="token punctuation">(</span>data<span class="token punctuation">,</span> delimiter <span class="token operator">=</span> <span class="token string">&apos;,&apos;</span><span class="token punctuation">,</span> omitFirstRow <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
data
<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>omitFirstRow <span class="token operator">?</span> data<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>v <span class="token operator">=&gt;</span> v<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span>delimiter<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">CSVToArray</span><span class="token punctuation">(</span><span class="token string">&apos;a,b\nc,d&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[&apos;a&apos;, &apos;b&apos;], [&apos;c&apos;, &apos;d&apos;]];</span>
<span class="token function">CSVToArray</span><span class="token punctuation">(</span><span class="token string">&apos;a;b\nc;d&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[&apos;a&apos;, &apos;b&apos;], [&apos;c&apos;, &apos;d&apos;]];</span>
<span class="token function">CSVToArray</span><span class="token punctuation">(</span><span class="token string">&apos;col1,col2\na,b\nc,d&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;,&apos;</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[&apos;a&apos;, &apos;b&apos;], [&apos;c&apos;, &apos;d&apos;]];</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: CSVToJSON">title: CSVToJSON</h2>
<p>Converts a comma-separated values (CSV) string to a 2D array of objects.<br>
The first row of the string is used as the title row.</p>
<ul>
<li>Use <code>Array.prototype.slice()</code> and <code>Array.prototype.indexOf(&apos;\n&apos;)</code> and <code>String.prototype.split(delimiter)</code> to separate the first row (title row) into values.</li>
<li>Use <code>String.prototype.split(&apos;\n&apos;)</code> to create a string for each row, then <code>Array.prototype.map()</code> and <code>String.prototype.split(delimiter)</code> to separate the values in each row.</li>
<li>Use <code>Array.prototype.reduce()</code> to create an object for each row&apos;s values, with the keys parsed from the title row.</li>
<li>Omit the second argument, <code>delimiter</code>, to use a default delimiter of <code>,</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> CSVToJSON <span class="token operator">=</span> <span class="token punctuation">(</span>data<span class="token punctuation">,</span> delimiter <span class="token operator">=</span> <span class="token string">&apos;,&apos;</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> titles <span class="token operator">=</span> data<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span>delimiter<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> data
<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>v <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> values <span class="token operator">=</span> v<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span>delimiter<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> titles<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>
<span class="token punctuation">(</span>obj<span class="token punctuation">,</span> title<span class="token punctuation">,</span> index<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span>title<span class="token punctuation">]</span> <span class="token operator">=</span> values<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> obj<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">CSVToJSON</span><span class="token punctuation">(</span><span class="token string">&apos;col1,col2\na,b\nc,d&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [{&apos;col1&apos;: &apos;a&apos;, &apos;col2&apos;: &apos;b&apos;}, {&apos;col1&apos;: &apos;c&apos;, &apos;col2&apos;: &apos;d&apos;}];</span>
<span class="token function">CSVToJSON</span><span class="token punctuation">(</span><span class="token string">&apos;col1;col2\na;b\nc;d&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [{&apos;col1&apos;: &apos;a&apos;, &apos;col2&apos;: &apos;b&apos;}, {&apos;col1&apos;: &apos;c&apos;, &apos;col2&apos;: &apos;d&apos;}];</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: CSVToArray">title: CSVToArray</h2>
<p>Converts a comma-separated values (CSV) string to a 2D array.</p>
<ul>
<li>Use <code>Array.prototype.slice()</code> and <code>Array.prototype.indexOf(&apos;\n&apos;)</code> to remove the first row (title row) if <code>omitFirstRow</code> is <code>true</code>.</li>
<li>Use <code>String.prototype.split(&apos;\n&apos;)</code> to create a string for each row, then <code>String.prototype.split(delimiter)</code> to separate the values in each row.</li>
<li>Omit the second argument, <code>delimiter</code>, to use a default delimiter of <code>&apos;,&apos;</code>.</li>
<li>Omit the third argument, <code>omitFirstRow</code>, to include the first row (title row) of the CSV string.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> CSVToArray <span class="token operator">=</span> <span class="token punctuation">(</span>data<span class="token punctuation">,</span> delimiter <span class="token operator">=</span> <span class="token string">&apos;,&apos;</span><span class="token punctuation">,</span> omitFirstRow <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
data
<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>omitFirstRow <span class="token operator">?</span> data<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>v <span class="token operator">=&gt;</span> v<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span>delimiter<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">CSVToArray</span><span class="token punctuation">(</span><span class="token string">&apos;a,b\nc,d&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[&apos;a&apos;, &apos;b&apos;], [&apos;c&apos;, &apos;d&apos;]];</span>
<span class="token function">CSVToArray</span><span class="token punctuation">(</span><span class="token string">&apos;a;b\nc;d&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[&apos;a&apos;, &apos;b&apos;], [&apos;c&apos;, &apos;d&apos;]];</span>
<span class="token function">CSVToArray</span><span class="token punctuation">(</span><span class="token string">&apos;col1,col2\na,b\nc,d&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;,&apos;</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[&apos;a&apos;, &apos;b&apos;], [&apos;c&apos;, &apos;d&apos;]];</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: CSVToJSON">title: CSVToJSON</h2>
<p>Converts a comma-separated values (CSV) string to a 2D array of objects.<br>
The first row of the string is used as the title row.</p>
<ul>
<li>Use <code>Array.prototype.slice()</code> and <code>Array.prototype.indexOf(&apos;\n&apos;)</code> and <code>String.prototype.split(delimiter)</code> to separate the first row (title row) into values.</li>
<li>Use <code>String.prototype.split(&apos;\n&apos;)</code> to create a string for each row, then <code>Array.prototype.map()</code> and <code>String.prototype.split(delimiter)</code> to separate the values in each row.</li>
<li>Use <code>Array.prototype.reduce()</code> to create an object for each row&apos;s values, with the keys parsed from the title row.</li>
<li>Omit the second argument, <code>delimiter</code>, to use a default delimiter of <code>,</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> CSVToJSON <span class="token operator">=</span> <span class="token punctuation">(</span>data<span class="token punctuation">,</span> delimiter <span class="token operator">=</span> <span class="token string">&apos;,&apos;</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> titles <span class="token operator">=</span> data<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span>delimiter<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> data
<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>v <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> values <span class="token operator">=</span> v<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span>delimiter<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> titles<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>
<span class="token punctuation">(</span>obj<span class="token punctuation">,</span> title<span class="token punctuation">,</span> index<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span>title<span class="token punctuation">]</span> <span class="token operator">=</span> values<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> obj<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">CSVToJSON</span><span class="token punctuation">(</span><span class="token string">&apos;col1,col2\na,b\nc,d&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [{&apos;col1&apos;: &apos;a&apos;, &apos;col2&apos;: &apos;b&apos;}, {&apos;col1&apos;: &apos;c&apos;, &apos;col2&apos;: &apos;d&apos;}];</span>
<span class="token function">CSVToJSON</span><span class="token punctuation">(</span><span class="token string">&apos;col1;col2\na;b\nc;d&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [{&apos;col1&apos;: &apos;a&apos;, &apos;col2&apos;: &apos;b&apos;}, {&apos;col1&apos;: &apos;c&apos;, &apos;col2&apos;: &apos;d&apos;}];</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: HSBToRGB">title: HSBToRGB</h2>
<p>Converts a HSB color tuple to RGB format.</p>
<ul>
<li>Use the <a href="https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB">HSB to RGB conversion formula</a> to convert to the appropriate format.</li>
<li>The range of the input parameters is H: [0, 360], S: [0, 100], B: [0, 100].</li>
<li>The range of all output values is [0, 255].</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">HSBToRGB</span> <span class="token operator">=</span> <span class="token punctuation">(</span>h<span class="token punctuation">,</span> s<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
s <span class="token operator">/=</span> <span class="token number">100</span><span class="token punctuation">;</span>
b <span class="token operator">/=</span> <span class="token number">100</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">k</span> <span class="token operator">=</span> <span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>n <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">60</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">6</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">f</span> <span class="token operator">=</span> <span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> b <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">-</span> s <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span><span class="token function">k</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">4</span> <span class="token operator">-</span> <span class="token function">k</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token punctuation">[</span><span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">HSBToRGB</span><span class="token punctuation">(</span><span class="token number">18</span><span class="token punctuation">,</span> <span class="token number">81</span><span class="token punctuation">,</span> <span class="token number">99</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [252.45, 109.31084999999996, 47.965499999999984]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: HSLToRGB">title: HSLToRGB</h2>
<p>Converts a HSL color tuple to RGB format.</p>
<ul>
<li>Use the <a href="https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB">HSL to RGB conversion formula</a> to convert to the appropriate format.</li>
<li>The range of the input parameters is H: [0, 360], S: [0, 100], L: [0, 100].</li>
<li>The range of all output values is [0, 255].</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">HSLToRGB</span> <span class="token operator">=</span> <span class="token punctuation">(</span>h<span class="token punctuation">,</span> s<span class="token punctuation">,</span> l<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
s <span class="token operator">/=</span> <span class="token number">100</span><span class="token punctuation">;</span>
l <span class="token operator">/=</span> <span class="token number">100</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">k</span> <span class="token operator">=</span> n <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>n <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">30</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">12</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> a <span class="token operator">=</span> s <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>l<span class="token punctuation">,</span> <span class="token number">1</span> <span class="token operator">-</span> l<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">f</span> <span class="token operator">=</span> n <span class="token operator">=&gt;</span>
l <span class="token operator">-</span> a <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span><span class="token function">k</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">3</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span><span class="token number">9</span> <span class="token operator">-</span> <span class="token function">k</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token punctuation">[</span><span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">HSLToRGB</span><span class="token punctuation">(</span><span class="token number">13</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [56.1, 12.155, 0]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: JSONToFile">title: JSONToFile</h2>
<p>Writes a JSON object to a file.</p>
<ul>
<li>Use <code>fs.writeFileSync()</code>, template literals and <code>JSON.stringify()</code> to write a <code>json</code> object to a <code>.json</code> file.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> fs <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&apos;fs&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">JSONToFile</span> <span class="token operator">=</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> filename<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
fs<span class="token punctuation">.</span><span class="token function">writeFileSync</span><span class="token punctuation">(</span><span class="token template-string"><span class="token string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>filename<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.json`</span></span><span class="token punctuation">,</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token keyword keyword-null">null</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">JSONToFile</span><span class="token punctuation">(</span><span class="token punctuation">{</span> test<span class="token punctuation">:</span> <span class="token string">&apos;is passed&apos;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">&apos;testJsonFile&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// writes the object to &apos;testJsonFile.json&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: JSONtoCSV">title: JSONtoCSV</h2>
<p>Converts an array of objects to a comma-separated values (CSV) string that contains only the <code>columns</code> specified.</p>
<ul>
<li>Use <code>Array.prototype.join(delimiter)</code> to combine all the names in <code>columns</code> to create the first row.</li>
<li>Use <code>Array.prototype.map()</code> and <code>Array.prototype.reduce()</code> to create a row for each object. Substitute non-existent values with empty strings and only mapping values in <code>columns</code>.</li>
<li>Use <code>Array.prototype.join(&apos;\n&apos;)</code> to combine all rows into a string.</li>
<li>Omit the third argument, <code>delimiter</code>, to use a default delimiter of <code>&apos;,&apos;</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> JSONtoCSV <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> columns<span class="token punctuation">,</span> delimiter <span class="token operator">=</span> <span class="token string">&apos;,&apos;</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token punctuation">[</span>
columns<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span>delimiter<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token operator">...</span>arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>obj <span class="token operator">=&gt;</span>
columns<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>
<span class="token punctuation">(</span>acc<span class="token punctuation">,</span> key<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token template-string"><span class="token string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>acc<span class="token interpolation-punctuation punctuation">}</span></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token operator">!</span>acc<span class="token punctuation">.</span>length <span class="token operator">?</span> <span class="token string">&apos;&apos;</span> <span class="token punctuation">:</span> delimiter<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&quot;</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token operator">!</span>obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">?</span> <span class="token string">&apos;&apos;</span> <span class="token punctuation">:</span> obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&quot;`</span></span><span class="token punctuation">,</span>
<span class="token string">&apos;&apos;</span>
<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">JSONtoCSV</span><span class="token punctuation">(</span>
<span class="token punctuation">[</span><span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> b<span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">3</span><span class="token punctuation">,</span> b<span class="token punctuation">:</span> <span class="token number">4</span><span class="token punctuation">,</span> c<span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> b<span class="token punctuation">:</span> <span class="token number">7</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;b&apos;</span><span class="token punctuation">]</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;a,b\n&quot;1&quot;,&quot;2&quot;\n&quot;3&quot;,&quot;4&quot;\n&quot;6&quot;,&quot;&quot;\n&quot;&quot;,&quot;7&quot;&apos;</span>
<span class="token function">JSONtoCSV</span><span class="token punctuation">(</span>
<span class="token punctuation">[</span><span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> b<span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">3</span><span class="token punctuation">,</span> b<span class="token punctuation">:</span> <span class="token number">4</span><span class="token punctuation">,</span> c<span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> b<span class="token punctuation">:</span> <span class="token number">7</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;b&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token string">&apos;;&apos;</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;a;b\n&quot;1&quot;;&quot;2&quot;\n&quot;3&quot;;&quot;4&quot;\n&quot;6&quot;;&quot;&quot;\n&quot;&quot;;&quot;7&quot;&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: RGBToHSB">title: RGBToHSB</h2>
<p>Converts a RGB color tuple to HSB format.</p>
<ul>
<li>Use the <a href="https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB">RGB to HSB conversion formula</a> to convert to the appropriate format.</li>
<li>The range of all input parameters is [0, 255].</li>
<li>The range of the resulting values is H: [0, 360], S: [0, 100], B: [0, 100].</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">RGBToHSB</span> <span class="token operator">=</span> <span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
r <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
g <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
b <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> v <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">,</span>
n <span class="token operator">=</span> v <span class="token operator">-</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> h <span class="token operator">=</span>
n <span class="token operator">===</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token number">0</span> <span class="token punctuation">:</span> n <span class="token operator">&amp;&amp;</span> v <span class="token operator">===</span> r <span class="token operator">?</span> <span class="token punctuation">(</span>g <span class="token operator">-</span> b<span class="token punctuation">)</span> <span class="token operator">/</span> n <span class="token punctuation">:</span> v <span class="token operator">===</span> g <span class="token operator">?</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token punctuation">(</span>b <span class="token operator">-</span> r<span class="token punctuation">)</span> <span class="token operator">/</span> n <span class="token punctuation">:</span> <span class="token number">4</span> <span class="token operator">+</span> <span class="token punctuation">(</span>r <span class="token operator">-</span> g<span class="token punctuation">)</span> <span class="token operator">/</span> n<span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token punctuation">[</span><span class="token number">60</span> <span class="token operator">*</span> <span class="token punctuation">(</span>h <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">?</span> h <span class="token operator">+</span> <span class="token number">6</span> <span class="token punctuation">:</span> h<span class="token punctuation">)</span><span class="token punctuation">,</span> v <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>n <span class="token operator">/</span> v<span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span><span class="token punctuation">,</span> v <span class="token operator">*</span> <span class="token number">100</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">RGBToHSB</span><span class="token punctuation">(</span><span class="token number">252</span><span class="token punctuation">,</span> <span class="token number">111</span><span class="token punctuation">,</span> <span class="token number">48</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [18.529411764705856, 80.95238095238095, 98.82352941176471]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: RGBToHSL">title: RGBToHSL</h2>
<p>Converts a RGB color tuple to HSL format.</p>
<ul>
<li>Use the <a href="https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/">RGB to HSL conversion formula</a> to convert to the appropriate format.</li>
<li>The range of all input parameters is [0, 255].</li>
<li>The range of the resulting values is H: [0, 360], S: [0, 100], L: [0, 100].</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">RGBToHSL</span> <span class="token operator">=</span> <span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
r <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
g <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
b <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> l <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> s <span class="token operator">=</span> l <span class="token operator">-</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> h <span class="token operator">=</span> s
<span class="token operator">?</span> l <span class="token operator">===</span> r
<span class="token operator">?</span> <span class="token punctuation">(</span>g <span class="token operator">-</span> b<span class="token punctuation">)</span> <span class="token operator">/</span> s
<span class="token punctuation">:</span> l <span class="token operator">===</span> g
<span class="token operator">?</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token punctuation">(</span>b <span class="token operator">-</span> r<span class="token punctuation">)</span> <span class="token operator">/</span> s
<span class="token punctuation">:</span> <span class="token number">4</span> <span class="token operator">+</span> <span class="token punctuation">(</span>r <span class="token operator">-</span> g<span class="token punctuation">)</span> <span class="token operator">/</span> s
<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token punctuation">[</span>
<span class="token number">60</span> <span class="token operator">*</span> h <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token number">60</span> <span class="token operator">*</span> h <span class="token operator">+</span> <span class="token number">360</span> <span class="token punctuation">:</span> <span class="token number">60</span> <span class="token operator">*</span> h<span class="token punctuation">,</span>
<span class="token number">100</span> <span class="token operator">*</span> <span class="token punctuation">(</span>s <span class="token operator">?</span> <span class="token punctuation">(</span>l <span class="token operator">&lt;=</span> <span class="token number">0.5</span> <span class="token operator">?</span> s <span class="token operator">/</span> <span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">*</span> l <span class="token operator">-</span> s<span class="token punctuation">)</span> <span class="token punctuation">:</span> s <span class="token operator">/</span> <span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">*</span> l <span class="token operator">-</span> s<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span><span class="token number">100</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">*</span> l <span class="token operator">-</span> s<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">RGBToHSL</span><span class="token punctuation">(</span><span class="token number">45</span><span class="token punctuation">,</span> <span class="token number">23</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [21.17647, 60.71428, 10.98039]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: RGBToHex">title: RGBToHex</h2>
<p>Converts the values of RGB components to a hexadecimal color code.</p>
<ul>
<li>Convert given RGB parameters to hexadecimal string using bitwise left-shift operator (<code>&lt;&lt;</code>) and <code>Number.prototype.toString(16)</code>.</li>
<li>Use <code>String.prototype.padStart(6, &apos;0&apos;)</code> to get a 6-digit hexadecimal value.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">RGBToHex</span> <span class="token operator">=</span> <span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token punctuation">(</span><span class="token punctuation">(</span>r <span class="token operator">&lt;&lt;</span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token punctuation">(</span>g <span class="token operator">&lt;&lt;</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token operator">+</span> b<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">padStart</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">,</span> <span class="token string">&apos;0&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">RGBToHex</span><span class="token punctuation">(</span><span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">165</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;ffa501&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: URLJoin">title: URLJoin</h2>
<p>Joins all given URL segments together, then normalizes the resulting URL.</p>
<ul>
<li>Use <code>String.prototype.join(&apos;/&apos;)</code> to combine URL segments.</li>
<li>Use a series of <code>String.prototype.replace()</code> calls with various regexps to normalize the resulting URL (remove double slashes, add proper slashes for protocol, remove slashes before parameters, combine parameters with <code>&apos;&amp;&apos;</code> and normalize first parameter delimiter).</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">URLJoin</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
args
<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;/&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/[\/]+/g</span><span class="token punctuation">,</span> <span class="token string">&apos;/&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/^(.+):\//</span><span class="token punctuation">,</span> <span class="token string">&apos;$1://&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/^file:/</span><span class="token punctuation">,</span> <span class="token string">&apos;file:/&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/\/(\?|&amp;|#[^!])/g</span><span class="token punctuation">,</span> <span class="token string">&apos;$1&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/\?/g</span><span class="token punctuation">,</span> <span class="token string">&apos;&amp;&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">&apos;&amp;&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;?&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">URLJoin</span><span class="token punctuation">(</span><span class="token string">&apos;http://www.google.com&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;/b/cd&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;?foo=123&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;?bar=foo&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// &apos;http://www.google.com/a/b/cd?foo=123&amp;bar=foo&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: UUIDGeneratorBrowser">title: UUIDGeneratorBrowser</h2>
<p>Generates a UUID in a browser.</p>
<ul>
<li>Use <code>Crypto.getRandomValues()</code> to generate a UUID, compliant with <a href="https://www.ietf.org/rfc/rfc4122.txt">RFC4122</a> version 4.</li>
<li>Use <code>Number.prototype.toString(16)</code> to convert it to a proper UUID.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">UUIDGeneratorBrowser</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1e7</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">1e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">4e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">8e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">1e11</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/[018]/g</span><span class="token punctuation">,</span> c <span class="token operator">=&gt;</span>
<span class="token punctuation">(</span>
c <span class="token operator">^</span>
<span class="token punctuation">(</span>crypto<span class="token punctuation">.</span><span class="token function">getRandomValues</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Uint8Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">&amp;</span> <span class="token punctuation">(</span><span class="token number">15</span> <span class="token operator">&gt;&gt;</span> <span class="token punctuation">(</span>c <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">UUIDGeneratorBrowser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;7982fcfe-5721-4632-bede-6000885be57d&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: UUIDGeneratorNode">title: UUIDGeneratorNode</h2>
<p>Generates a UUID in Node.JS.</p>
<ul>
<li>Use <code>crypto.randomBytes()</code> to generate a UUID, compliant with <a href="https://www.ietf.org/rfc/rfc4122.txt">RFC4122</a> version 4.</li>
<li>Use <code>Number.prototype.toString(16)</code> to convert it to a proper UUID.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> crypto <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&apos;crypto&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">UUIDGeneratorNode</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1e7</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">1e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">4e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">8e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">1e11</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/[018]/g</span><span class="token punctuation">,</span> c <span class="token operator">=&gt;</span>
<span class="token punctuation">(</span>c <span class="token operator">^</span> <span class="token punctuation">(</span>crypto<span class="token punctuation">.</span><span class="token function">randomBytes</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">&amp;</span> <span class="token punctuation">(</span><span class="token number">15</span> <span class="token operator">&gt;&gt;</span> <span class="token punctuation">(</span>c <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">UUIDGeneratorNode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;79c7c136-60ee-40a2-beb2-856f1feabefc&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: accumulate">title: accumulate</h2>
<p>Creates an array of partial sums.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code>, initialized with an empty array accumulator to iterate over <code>nums</code>.</li>
<li>Use <code>Array.prototype.slice(-1)</code>, the spread operator (<code>...</code>) and the unary <code>+</code> operator to add each value to the accumulator array containing the previous sums.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">accumulate</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">...</span>nums<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
nums<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">[</span><span class="token operator">...</span>acc<span class="token punctuation">,</span> n <span class="token operator">+</span> <span class="token operator">+</span>acc<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">accumulate</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 3, 6, 10]</span>
<span class="token function">accumulate</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 3, 6, 10]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addClass">title: addClass</h2>
<p>Adds a class to an HTML element.</p>
<ul>
<li>Use <code>Element.classList</code> and <code>DOMTokenList.add()</code> to add the specified class to the element.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addClass</span> <span class="token operator">=</span> <span class="token punctuation">(</span>el<span class="token punctuation">,</span> className<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> el<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>className<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addClass</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">&apos;p&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">&apos;special&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// The paragraph will now have the &apos;special&apos; class</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addDaysToDate">title: addDaysToDate</h2>
<p>Calculates the date of <code>n</code> days from the given date, returning its string representation.</p>
<ul>
<li>Use <code>new Date()</code> to create a date object from the first argument.</li>
<li>Use <code>Date.prototype.getDate()</code> and <code>Date.prototype.setDate()</code> to add <code>n</code> days to the given date.</li>
<li>Use <code>Date.prototype.toISOString()</code> to return a string in <code>yyyy-mm-dd</code> format.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addDaysToDate</span> <span class="token operator">=</span> <span class="token punctuation">(</span>date<span class="token punctuation">,</span> n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> d <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span>
d<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> d<span class="token punctuation">.</span><span class="token function">toISOString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&apos;T&apos;</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addDaysToDate</span><span class="token punctuation">(</span><span class="token string">&apos;2020-10-15&apos;</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;2020-10-25&apos;</span>
<span class="token function">addDaysToDate</span><span class="token punctuation">(</span><span class="token string">&apos;2020-10-15&apos;</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;2020-10-05&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addEventListenerAll">title: addEventListenerAll</h2>
<p>Attaches an event listener to all the provided targets.</p>
<ul>
<li>Use <code>Array.prototype.forEach()</code> and <code>EventTarget.addEventListener()</code> to attach the provided <code>listener</code> for the given event <code>type</code> to all <code>targets</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addEventListenerAll</span> <span class="token operator">=</span> <span class="token punctuation">(</span>targets<span class="token punctuation">,</span> type<span class="token punctuation">,</span> listener<span class="token punctuation">,</span> options<span class="token punctuation">,</span> useCapture<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
targets<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>target <span class="token operator">=&gt;</span>
target<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> listener<span class="token punctuation">,</span> options<span class="token punctuation">,</span> useCapture<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addEventListenerAll</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">&apos;click&apos;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&apos;Clicked a link&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Logs &apos;Clicked a link&apos; whenever any anchor element is clicked</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addMinutesToDate">title: addMinutesToDate</h2>
<p>Calculates the date of <code>n</code> minutes from the given date, returning its string representation.</p>
<ul>
<li>Use <code>new Date()</code> to create a date object from the first argument.</li>
<li>Use <code>Date.prototype.getTime()</code> and <code>Date.prototype.setTime()</code> to add <code>n</code> minutes to the given date.</li>
<li>Use <code>Date.prototype.toISOString()</code>, <code>String.prototype.split()</code> and <code>String.prototype.replace()</code> to return a string in <code>yyyy-mm-dd HH:MM:SS</code> format.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addMinutesToDate</span> <span class="token operator">=</span> <span class="token punctuation">(</span>date<span class="token punctuation">,</span> n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> d <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span>
d<span class="token punctuation">.</span><span class="token function">setTime</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> n <span class="token operator">*</span> <span class="token number">60000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> d<span class="token punctuation">.</span><span class="token function">toISOString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&apos;.&apos;</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">&apos;T&apos;</span><span class="token punctuation">,</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addMinutesToDate</span><span class="token punctuation">(</span><span class="token string">&apos;2020-10-19 12:00:00&apos;</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;2020-10-19 12:10:00&apos;</span>
<span class="token function">addMinutesToDate</span><span class="token punctuation">(</span><span class="token string">&apos;2020-10-19&apos;</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;2020-10-18 23:50:00&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addMultipleListeners">title: addMultipleListeners</h2>
<p>Adds multiple event listeners with the same handler to an element.</p>
<ul>
<li>Use <code>Array.prototype.forEach()</code> and <code>EventTarget.addEventListener()</code> to add multiple event listeners with an assigned callback function to an element.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addMultipleListeners</span> <span class="token operator">=</span> <span class="token punctuation">(</span>el<span class="token punctuation">,</span> types<span class="token punctuation">,</span> listener<span class="token punctuation">,</span> options<span class="token punctuation">,</span> useCapture<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
types<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>type <span class="token operator">=&gt;</span>
el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> listener<span class="token punctuation">,</span> options<span class="token punctuation">,</span> useCapture<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addMultipleListeners</span><span class="token punctuation">(</span>
document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">&apos;.my-element&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">&apos;click&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;mousedown&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&apos;hello!&apos;</span><span class="token punctuation">)</span> <span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addStyles">title: addStyles</h2>
<p>Adds the provided styles to the given element.</p>
<ul>
<li>Use <code>Object.assign()</code> and <code>ElementCSSInlineStyle.style</code> to merge the provided <code>styles</code> object into the style of the given element.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addStyles</span> <span class="token operator">=</span> <span class="token punctuation">(</span>el<span class="token punctuation">,</span> styles<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span>el<span class="token punctuation">.</span>style<span class="token punctuation">,</span> styles<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addStyles</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">&apos;my-element&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
background<span class="token punctuation">:</span> <span class="token string">&apos;red&apos;</span><span class="token punctuation">,</span>
color<span class="token punctuation">:</span> <span class="token string">&apos;#ffff00&apos;</span><span class="token punctuation">,</span>
fontSize<span class="token punctuation">:</span> <span class="token string">&apos;3rem&apos;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addWeekDays">title: addWeekDays</h2>
<p>Calculates the date after adding the given number of business days.</p>
<ul>
<li>Use <code>Array.from()</code> to construct an array with <code>length</code> equal to the <code>count</code> of business days to be added.</li>
<li>Use <code>Array.prototype.reduce()</code> to iterate over the array, starting from <code>startDate</code> and incrementing, using <code>Date.prototype.getDate()</code> and <code>Date.prototype.setDate()</code>.</li>
<li>If the current <code>date</code> is on a weekend, update it again by adding either one day or two days to make it a weekday.</li>
<li><strong>NOTE:</strong> Does not take official holidays into account.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addWeekDays</span> <span class="token operator">=</span> <span class="token punctuation">(</span>startDate<span class="token punctuation">,</span> count<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Array<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span><span class="token punctuation">{</span> length<span class="token punctuation">:</span> count <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>date <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
date <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">6</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span>
date <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">6</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> date<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> startDate<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addWeekDays</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">&apos;Oct 09, 2020&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Oct 16, 2020&apos;</span>
<span class="token function">addWeekDays</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">&apos;Oct 12, 2020&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Oct 19, 2020&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: all">title: all</h2>
<p>Checks if the provided predicate function returns <code>true</code> for all elements in a collection.</p>
<ul>
<li>Use <code>Array.prototype.every()</code> to test if all elements in the collection return <code>true</code> based on <code>fn</code>.</li>
<li>Omit the second argument, <code>fn</code>, to use <code>Boolean</code> as a default.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">all</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn <span class="token operator">=</span> Boolean<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> x <span class="token operator">=&gt;</span> x <span class="token operator">&gt;</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: allEqual">title: allEqual</h2>
<p>Checks if all elements in an array are equal.</p>
<ul>
<li>Use <code>Array.prototype.every()</code> to check if all the elements of the array are the same as the first one.</li>
<li>Elements in the array are compared using the strict comparison operator, which does not account for <code>NaN</code> self-inequality.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">allEqual</span> <span class="token operator">=</span> arr <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span>val <span class="token operator">=&gt;</span> val <span class="token operator">===</span> arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">allEqual</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token function">allEqual</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: allEqualBy">title: allEqualBy</h2>
<p>Checks if all elements in an array are equal, based on the provided mapping function.</p>
<ul>
<li>Apply <code>fn</code> to the first element of <code>arr</code>.</li>
<li>Use <code>Array.prototype.every()</code> to check if <code>fn</code> returns the same value for all elements in the array as it did for the first one.</li>
<li>Elements in the array are compared using the strict comparison operator, which does not account for <code>NaN</code> self-inequality.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">allEqualBy</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> eql <span class="token operator">=</span> <span class="token function">fn</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> arr<span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span>val <span class="token operator">=&gt;</span> <span class="token function">fn</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token operator">===</span> eql<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">allEqualBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span>round<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">allEqualBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">,</span> <span class="token number">1.6</span><span class="token punctuation">]</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span>round<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: allUnique">title: allUnique</h2>
<p>Checks if all elements in an array are unique.</p>
<ul>
<li>Create a new <code>Set</code> from the mapped values to keep only unique occurrences.</li>
<li>Use <code>Array.prototype.length</code> and <code>Set.prototype.size</code> to compare the length of the unique values to the original array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">allUnique</span> <span class="token operator">=</span> arr <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">.</span>size<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">allUnique</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">allUnique</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: allUniqueBy">title: allUniqueBy</h2>
<p>Checks if all elements in an array are unique, based on the provided mapping function.</p>
<ul>
<li>Use <code>Array.prototype.map()</code> to apply <code>fn</code> to all elements in <code>arr</code>.</li>
<li>Create a new <code>Set</code> from the mapped values to keep only unique occurrences.</li>
<li>Use <code>Array.prototype.length</code> and <code>Set.prototype.size</code> to compare the length of the unique mapped values to the original array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">allUniqueBy</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>size<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">allUniqueBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">2.4</span><span class="token punctuation">,</span> <span class="token number">2.9</span><span class="token punctuation">]</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span>round<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">allUniqueBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">2.3</span><span class="token punctuation">,</span> <span class="token number">2.4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span>round<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: and&lt;br&gt;
unlisted: true">title: and<br>
unlisted: true</h2>
<p>Checks if both arguments are <code>true</code>.</p>
<ul>
<li>Use the logical and (<code>&amp;&amp;</code>) operator on the two given values.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">and</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> a <span class="token operator">&amp;&amp;</span> b<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">and</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">and</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token function">and</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: any">title: any</h2>
<p>Checks if the provided predicate function returns <code>true</code> for at least one element in a collection.</p>
<ul>
<li>Use <code>Array.prototype.some()</code> to test if any elements in the collection return <code>true</code> based on <code>fn</code>.</li>
<li>Omit the second argument, <code>fn</code>, to use <code>Boolean</code> as a default.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">any</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn <span class="token operator">=</span> Boolean<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span><span class="token function">some</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">any</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> x <span class="token operator">=&gt;</span> x <span class="token operator">&gt;=</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">any</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: aperture">title: aperture</h2>
<p>Creates an array of <code>n</code>-tuples of consecutive elements.</p>
<ul>
<li>Use <code>Array.prototype.slice()</code> and <code>Array.prototype.map()</code> to create an array of appropriate length.</li>
<li>Populate the array with <code>n</code>-tuples of consecutive elements from <code>arr</code>.</li>
<li>If <code>n</code> is greater than the length of <code>arr</code>, return an empty array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">aperture</span> <span class="token operator">=</span> <span class="token punctuation">(</span>n<span class="token punctuation">,</span> arr<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
n <span class="token operator">&gt;</span> arr<span class="token punctuation">.</span>length
<span class="token operator">?</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
<span class="token punctuation">:</span> arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>v<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> i <span class="token operator">+</span> n<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">aperture</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[1, 2], [2, 3], [3, 4]]</span>
<span class="token function">aperture</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[1, 2, 3], [2, 3, 4]]</span>
<span class="token function">aperture</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// []</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: approximatelyEqual">title: approximatelyEqual</h2>
<p>Checks if two numbers are approximately equal to each other.</p>
<ul>
<li>Use <code>Math.abs()</code> to compare the absolute difference of the two values to <code>epsilon</code>.</li>
<li>Omit the third argument, <code>epsilon</code>, to use a default value of <code>0.001</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">approximatelyEqual</span> <span class="token operator">=</span> <span class="token punctuation">(</span>v1<span class="token punctuation">,</span> v2<span class="token punctuation">,</span> epsilon <span class="token operator">=</span> <span class="token number">0.001</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Math<span class="token punctuation">.</span><span class="token function">abs</span><span class="token punctuation">(</span>v1 <span class="token operator">-</span> v2<span class="token punctuation">)</span> <span class="token operator">&lt;</span> epsilon<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">approximatelyEqual</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token constant">PI</span> <span class="token operator">/</span> <span class="token number">2.0</span><span class="token punctuation">,</span> <span class="token number">1.5708</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: arithmeticProgression">title: arithmeticProgression</h2>
<p>Creates an array of numbers in the arithmetic progression, starting with the given positive integer and up to the specified limit.</p>
<ul>
<li>Use <code>Array.from()</code> to create an array of the desired length, <code>lim/n</code>. Use a map function to fill it with the desired values in the given range.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">arithmeticProgression</span> <span class="token operator">=</span> <span class="token punctuation">(</span>n<span class="token punctuation">,</span> lim<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Array<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span><span class="token punctuation">{</span> length<span class="token punctuation">:</span> Math<span class="token punctuation">.</span><span class="token function">ceil</span><span class="token punctuation">(</span>lim <span class="token operator">/</span> n<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>_<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">*</span> n <span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">arithmeticProgression</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">25</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [5, 10, 15, 20, 25]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: arrayToCSV">title: arrayToCSV</h2>
<p>Converts a 2D array to a comma-separated values (CSV) string.</p>
<ul>
<li>Use <code>Array.prototype.map()</code> and <code>Array.prototype.join(delimiter)</code> to combine individual 1D arrays (rows) into strings.</li>
<li>Use <code>Array.prototype.join(&apos;\n&apos;)</code> to combine all rows into a CSV string, separating each row with a newline.</li>
<li>Omit the second argument, <code>delimiter</code>, to use a default delimiter of <code>,</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> arrayToCSV <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> delimiter <span class="token operator">=</span> <span class="token string">&apos;,&apos;</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>v <span class="token operator">=&gt;</span>
v<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>x <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token function">isNaN</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token template-string"><span class="token string">`&quot;</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>x<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/&quot;/g</span><span class="token punctuation">,</span> <span class="token string">&apos;&quot;&quot;&apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&quot;`</span></span> <span class="token punctuation">:</span> x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span>delimiter<span class="token punctuation">)</span>
<span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">arrayToCSV</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;b&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;c&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;d&apos;</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;&quot;a&quot;,&quot;b&quot;\n&quot;c&quot;,&quot;d&quot;&apos;</span>
<span class="token function">arrayToCSV</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;b&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;c&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;d&apos;</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">&apos;;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;&quot;a&quot;;&quot;b&quot;\n&quot;c&quot;;&quot;d&quot;&apos;</span>
<span class="token function">arrayToCSV</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;&quot;b&quot; great&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;c&apos;</span><span class="token punctuation">,</span> <span class="token number">3.1415</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// &apos;&quot;a&quot;,&quot;&quot;&quot;b&quot;&quot; great&quot;\n&quot;c&quot;,3.1415&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: arrayToHTMLList">title: arrayToHTMLList</h2>
<p>Converts the given array elements into <code>&lt;li&gt;</code> tags and appends them to the list of the given id.</p>
<ul>
<li>Use <code>Array.prototype.map()</code> and <code>Document.querySelector()</code> to create a list of html tags.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">arrayToHTMLList</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> listID<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token template-string"><span class="token string">`#</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>listID<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">+=</span> arr
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>item <span class="token operator">=&gt;</span> <span class="token template-string"><span class="token string">`&lt;li&gt;</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>item<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/li&gt;`</span></span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">arrayToHTMLList</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">&apos;item 1&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;item 2&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">&apos;myListID&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: ary">title: ary</h2>
<p>Creates a function that accepts up to <code>n</code> arguments, ignoring any additional arguments.</p>
<ul>
<li>Call the provided function, <code>fn</code>, with up to <code>n</code> arguments, using <code>Array.prototype.slice(0, n)</code> and the spread operator (<code>...</code>).</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">ary</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> firstTwoMax <span class="token operator">=</span> <span class="token function">ary</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span>max<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token string">&apos;a&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>x <span class="token operator">=&gt;</span> <span class="token function">firstTwoMax</span><span class="token punctuation">(</span><span class="token operator">...</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [6, 6, 10]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: assertValidKeys">title: assertValidKeys</h2>
<p>Validates all keys in an object match the given <code>keys</code>.</p>
<ul>
<li>Use <code>Object.keys()</code> to get the keys of the given object, <code>obj</code>.</li>
<li>Use <code>Array.prototype.every()</code> and <code>Array.prototype.includes()</code> to validate that each key in the object is specified in the <code>keys</code> array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">assertValidKeys</span> <span class="token operator">=</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> keys<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span>key <span class="token operator">=&gt;</span> keys<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">assertValidKeys</span><span class="token punctuation">(</span><span class="token punctuation">{</span> id<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">&apos;apple&apos;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;id&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;name&apos;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">assertValidKeys</span><span class="token punctuation">(</span><span class="token punctuation">{</span> id<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">&apos;apple&apos;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;id&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;type&apos;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: atob">title: atob</h2>
<p>Decodes a string of data which has been encoded using base-64 encoding.</p>
<ul>
<li>Create a <code>Buffer</code> for the given string with base-64 encoding and use <code>Buffer.toString(&apos;binary&apos;)</code> to return the decoded string.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">atob</span> <span class="token operator">=</span> str <span class="token operator">=&gt;</span> Buffer<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span>str<span class="token punctuation">,</span> <span class="token string">&apos;base64&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token string">&apos;binary&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">atob</span><span class="token punctuation">(</span><span class="token string">&apos;Zm9vYmFy&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;foobar&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: attempt">title: attempt</h2>
<p>Attempts to invoke a function with the provided arguments, returning either the result or the caught error object.</p>
<ul>
<li>Use a <code>try... catch</code> block to return either the result of the function or an appropriate error.</li>
<li>If the caught object is not an <code>Error</code>, use it to create a new <code>Error</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">attempt</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-try">try</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword keyword-catch">catch</span> <span class="token punctuation">(</span><span class="token class-name">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> e <span class="token keyword keyword-instanceof">instanceof</span> <span class="token class-name">Error</span> <span class="token operator">?</span> e <span class="token punctuation">:</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-let">let</span> elements <span class="token operator">=</span> <span class="token function">attempt</span><span class="token punctuation">(</span><span class="token keyword keyword-function">function</span><span class="token punctuation">(</span>selector<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span>selector<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">&apos;&gt;_&gt;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>elements <span class="token keyword keyword-instanceof">instanceof</span> <span class="token class-name">Error</span><span class="token punctuation">)</span> elements <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// elements = []</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: average">title: average</h2>
<p>Calculates the average of two or more numbers.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code> to add each value to an accumulator, initialized with a value of <code>0</code>.</li>
<li>Divide the resulting array by its length.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">average</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">...</span>nums<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
nums<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> val<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> acc <span class="token operator">+</span> val<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">/</span> nums<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">average</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span>
<span class="token function">average</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: averageBy">title: averageBy</h2>
<p>Calculates the average of an array, after mapping each element to a value using the provided function.</p>
<ul>
<li>Use <code>Array.prototype.map()</code> to map each element to the value returned by <code>fn</code>.</li>
<li>Use <code>Array.prototype.reduce()</code> to add each value to an accumulator, initialized with a value of <code>0</code>.</li>
<li>Divide the resulting array by its length.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">averageBy</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword keyword-typeof">typeof</span> fn <span class="token operator">===</span> <span class="token string">&apos;function&apos;</span> <span class="token operator">?</span> fn <span class="token punctuation">:</span> val <span class="token operator">=&gt;</span> val<span class="token punctuation">[</span>fn<span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> val<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> acc <span class="token operator">+</span> val<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">/</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">averageBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">4</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">8</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span> o <span class="token operator">=&gt;</span> o<span class="token punctuation">.</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span>
<span class="token function">averageBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">4</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">8</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">&apos;n&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bifurcate">title: bifurcate</h2>
<p>Splits values into two groups, based on the result of the given <code>filter</code> array.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code> and <code>Array.prototype.push()</code> to add elements to groups, based on <code>filter</code>.</li>
<li>If <code>filter</code> has a truthy value for any element, add it to the first group, otherwise add it to the second group.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bifurcate</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> filter<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> val<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>acc<span class="token punctuation">[</span>filter<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">?</span> <span class="token number">0</span> <span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">,</span> acc<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">bifurcate</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">&apos;beep&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;boop&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;foo&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;bar&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [ [&apos;beep&apos;, &apos;boop&apos;, &apos;bar&apos;], [&apos;foo&apos;] ]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bifurcateBy">title: bifurcateBy</h2>
<p>Splits values into two groups, based on the result of the given filtering function.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code> and <code>Array.prototype.push()</code> to add elements to groups, based on the value returned by <code>fn</code> for each element.</li>
<li>If <code>fn</code> returns a truthy value for any element, add it to the first group, otherwise add it to the second group.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bifurcateBy</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> val<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>acc<span class="token punctuation">[</span><span class="token function">fn</span><span class="token punctuation">(</span>val<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token number">0</span> <span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">,</span> acc<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">bifurcateBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">&apos;beep&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;boop&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;foo&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;bar&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> x <span class="token operator">=&gt;</span> x<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token string">&apos;b&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [ [&apos;beep&apos;, &apos;boop&apos;, &apos;bar&apos;], [&apos;foo&apos;] ]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: binary">title: binary</h2>
<p>Creates a function that accepts up to two arguments, ignoring any additional arguments.</p>
<ul>
<li>Call the provided function, <code>fn</code>, with the first two arguments given.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">binary</span> <span class="token operator">=</span> fn <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">fn</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token punctuation">[</span><span class="token string">&apos;2&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;1&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;0&apos;</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token function">binary</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span>max<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [2, 1, 2]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: binarySearch">title: binarySearch</h2>
<p>Finds the index of a given element in a sorted array using the binary search algorithm.</p>
<ul>
<li>Declare the left and right search boundaries, <code>l</code> and <code>r</code>, initialized to <code>0</code> and the <code>length</code> of the array respectively.</li>
<li>Use a <code>while</code> loop to repeatedly narrow down the search subarray, using <code>Math.floor()</code> to cut it in half.</li>
<li>Return the index of the element if found, otherwise return <code>-1</code>.</li>
<li><strong>Note:</strong> Does not account for duplicate values in the array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">binarySearch</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> item<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> l <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span>
r <span class="token operator">=</span> arr<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword keyword-while">while</span> <span class="token punctuation">(</span>l <span class="token operator">&lt;=</span> r<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> mid <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span><span class="token punctuation">(</span>l <span class="token operator">+</span> r<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> guess <span class="token operator">=</span> arr<span class="token punctuation">[</span>mid<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>guess <span class="token operator">===</span> item<span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> mid<span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>guess <span class="token operator">&gt;</span> item<span class="token punctuation">)</span> r <span class="token operator">=</span> mid <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword keyword-else">else</span> l <span class="token operator">=</span> mid <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword keyword-return">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">binarySearch</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span>
<span class="token function">binarySearch</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span>
<span class="token function">binarySearch</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -1</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bind">title: bind</h2>
<p>Creates a function that invokes <code>fn</code> with a given context, optionally prepending any additional supplied parameters to the arguments.</p>
<ul>
<li>Return a <code>function</code> that uses <code>Function.prototype.apply()</code> to apply the given <code>context</code> to <code>fn</code>.</li>
<li>Use the spread operator (<code>...</code>) to prepend any additional supplied parameters to the arguments.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bind</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> context<span class="token punctuation">,</span> <span class="token operator">...</span>boundArgs<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
fn<span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token operator">...</span>boundArgs<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-function">function</span> <span class="token function">greet</span><span class="token punctuation">(</span>greeting<span class="token punctuation">,</span> punctuation<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> greeting <span class="token operator">+</span> <span class="token string">&apos; &apos;</span> <span class="token operator">+</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>user <span class="token operator">+</span> punctuation<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword keyword-const">const</span> freddy <span class="token operator">=</span> <span class="token punctuation">{</span> user<span class="token punctuation">:</span> <span class="token string">&apos;fred&apos;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> freddyBound <span class="token operator">=</span> <span class="token function">bind</span><span class="token punctuation">(</span>greet<span class="token punctuation">,</span> freddy<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">freddyBound</span><span class="token punctuation">(</span><span class="token string">&apos;hi&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;!&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;hi fred!&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bindAll">title: bindAll</h2>
<p>Binds methods of an object to the object itself, overwriting the existing method.</p>
<ul>
<li>Use <code>Array.prototype.forEach()</code> to iterate over the given <code>fns</code>.</li>
<li>Return a function for each one, using <code>Function.prototype.apply()</code> to apply the given context (<code>obj</code>) to <code>fn</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bindAll</span> <span class="token operator">=</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token operator">...</span>fns<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
fns<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>
fn <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
<span class="token punctuation">(</span>f <span class="token operator">=</span> obj<span class="token punctuation">[</span>fn<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span>obj<span class="token punctuation">[</span>fn<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword keyword-function">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> f<span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-let">let</span> view <span class="token operator">=</span> <span class="token punctuation">{</span>
label<span class="token punctuation">:</span> <span class="token string">&apos;docs&apos;</span><span class="token punctuation">,</span>
click<span class="token punctuation">:</span> <span class="token keyword keyword-function">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&apos;clicked &apos;</span> <span class="token operator">+</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>label<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token function">bindAll</span><span class="token punctuation">(</span>view<span class="token punctuation">,</span> <span class="token string">&apos;click&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">&apos;click&apos;</span><span class="token punctuation">,</span> view<span class="token punctuation">.</span>click<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Log &apos;clicked docs&apos; when clicked.</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bindKey">title: bindKey</h2>
<p>Creates a function that invokes the method at a given key of an object, optionally prepending any additional supplied parameters to the arguments.</p>
<ul>
<li>Return a <code>function</code> that uses <code>Function.prototype.apply()</code> to bind <code>context[fn]</code> to <code>context</code>.</li>
<li>Use the spread operator (<code>...</code>) to prepend any additional supplied parameters to the arguments.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bindKey</span> <span class="token operator">=</span> <span class="token punctuation">(</span>context<span class="token punctuation">,</span> fn<span class="token punctuation">,</span> <span class="token operator">...</span>boundArgs<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
context<span class="token punctuation">[</span>fn<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token operator">...</span>boundArgs<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> freddy <span class="token operator">=</span> <span class="token punctuation">{</span>
user<span class="token punctuation">:</span> <span class="token string">&apos;fred&apos;</span><span class="token punctuation">,</span>
greet<span class="token punctuation">:</span> <span class="token keyword keyword-function">function</span><span class="token punctuation">(</span>greeting<span class="token punctuation">,</span> punctuation<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> greeting <span class="token operator">+</span> <span class="token string">&apos; &apos;</span> <span class="token operator">+</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>user <span class="token operator">+</span> punctuation<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> freddyBound <span class="token operator">=</span> <span class="token function">bindKey</span><span class="token punctuation">(</span>freddy<span class="token punctuation">,</span> <span class="token string">&apos;greet&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">freddyBound</span><span class="token punctuation">(</span><span class="token string">&apos;hi&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;!&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;hi fred!&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: binomialCoefficient">title: binomialCoefficient</h2>
<p>Calculates the number of ways to choose <code>k</code> items from <code>n</code> items without repetition and without order.</p>
<ul>
<li>Use <code>Number.isNaN()</code> to check if any of the two values is <code>NaN</code>.</li>
<li>Check if <code>k</code> is less than <code>0</code>, greater than or equal to <code>n</code>, equal to <code>1</code> or <code>n - 1</code> and return the appropriate result.</li>
<li>Check if <code>n - k</code> is less than <code>k</code> and switch their values accordingly.</li>
<li>Loop from <code>2</code> through <code>k</code> and calculate the binomial coefficient.</li>
<li>Use <code>Math.round()</code> to account for rounding errors in the calculation.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">binomialCoefficient</span> <span class="token operator">=</span> <span class="token punctuation">(</span>n<span class="token punctuation">,</span> k<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">||</span> Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> <span class="token number">NaN</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>k <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">||</span> k <span class="token operator">&gt;</span> n<span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>k <span class="token operator">===</span> <span class="token number">0</span> <span class="token operator">||</span> k <span class="token operator">===</span> n<span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>k <span class="token operator">===</span> <span class="token number">1</span> <span class="token operator">||</span> k <span class="token operator">===</span> n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> n<span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>n <span class="token operator">-</span> k <span class="token operator">&lt;</span> k<span class="token punctuation">)</span> k <span class="token operator">=</span> n <span class="token operator">-</span> k<span class="token punctuation">;</span>
<span class="token keyword keyword-let">let</span> res <span class="token operator">=</span> n<span class="token punctuation">;</span>
<span class="token keyword keyword-for">for</span> <span class="token punctuation">(</span><span class="token keyword keyword-let">let</span> j <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> j <span class="token operator">&lt;=</span> k<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> res <span class="token operator">*=</span> <span class="token punctuation">(</span>n <span class="token operator">-</span> j <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">/</span> j<span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> Math<span class="token punctuation">.</span><span class="token function">round</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">binomialCoefficient</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 28</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: both&lt;br&gt;
unlisted: true">title: both<br>
unlisted: true</h2>
<p>Checks if both of the given functions return <code>true</code> for a given set of arguments.</p>
<ul>
<li>Use the logical and (<code>&amp;&amp;</code>) operator on the result of calling the two functions with the supplied <code>args</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">both</span> <span class="token operator">=</span> <span class="token punctuation">(</span>f<span class="token punctuation">,</span> g<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token function">g</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">isEven</span> <span class="token operator">=</span> num <span class="token operator">=&gt;</span> num <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">isPositive</span> <span class="token operator">=</span> num <span class="token operator">=&gt;</span> num <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> isPositiveEven <span class="token operator">=</span> <span class="token function">both</span><span class="token punctuation">(</span>isEven<span class="token punctuation">,</span> isPositive<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">isPositiveEven</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">isPositiveEven</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: HSBToRGB">title: HSBToRGB</h2>
<p>Converts a HSB color tuple to RGB format.</p>
<ul>
<li>Use the <a href="https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB">HSB to RGB conversion formula</a> to convert to the appropriate format.</li>
<li>The range of the input parameters is H: [0, 360], S: [0, 100], B: [0, 100].</li>
<li>The range of all output values is [0, 255].</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">HSBToRGB</span> <span class="token operator">=</span> <span class="token punctuation">(</span>h<span class="token punctuation">,</span> s<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
s <span class="token operator">/=</span> <span class="token number">100</span><span class="token punctuation">;</span>
b <span class="token operator">/=</span> <span class="token number">100</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">k</span> <span class="token operator">=</span> <span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>n <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">60</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">6</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">f</span> <span class="token operator">=</span> <span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> b <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">-</span> s <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span><span class="token function">k</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">4</span> <span class="token operator">-</span> <span class="token function">k</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token punctuation">[</span><span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">HSBToRGB</span><span class="token punctuation">(</span><span class="token number">18</span><span class="token punctuation">,</span> <span class="token number">81</span><span class="token punctuation">,</span> <span class="token number">99</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [252.45, 109.31084999999996, 47.965499999999984]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: HSLToRGB">title: HSLToRGB</h2>
<p>Converts a HSL color tuple to RGB format.</p>
<ul>
<li>Use the <a href="https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB">HSL to RGB conversion formula</a> to convert to the appropriate format.</li>
<li>The range of the input parameters is H: [0, 360], S: [0, 100], L: [0, 100].</li>
<li>The range of all output values is [0, 255].</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">HSLToRGB</span> <span class="token operator">=</span> <span class="token punctuation">(</span>h<span class="token punctuation">,</span> s<span class="token punctuation">,</span> l<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
s <span class="token operator">/=</span> <span class="token number">100</span><span class="token punctuation">;</span>
l <span class="token operator">/=</span> <span class="token number">100</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">k</span> <span class="token operator">=</span> n <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>n <span class="token operator">+</span> h <span class="token operator">/</span> <span class="token number">30</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">12</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> a <span class="token operator">=</span> s <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>l<span class="token punctuation">,</span> <span class="token number">1</span> <span class="token operator">-</span> l<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">f</span> <span class="token operator">=</span> n <span class="token operator">=&gt;</span>
l <span class="token operator">-</span> a <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span><span class="token function">k</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">3</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span><span class="token number">9</span> <span class="token operator">-</span> <span class="token function">k</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token punctuation">[</span><span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">255</span> <span class="token operator">*</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">HSLToRGB</span><span class="token punctuation">(</span><span class="token number">13</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [56.1, 12.155, 0]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: JSONToFile">title: JSONToFile</h2>
<p>Writes a JSON object to a file.</p>
<ul>
<li>Use <code>fs.writeFileSync()</code>, template literals and <code>JSON.stringify()</code> to write a <code>json</code> object to a <code>.json</code> file.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> fs <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&apos;fs&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">JSONToFile</span> <span class="token operator">=</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> filename<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
fs<span class="token punctuation">.</span><span class="token function">writeFileSync</span><span class="token punctuation">(</span><span class="token template-string"><span class="token string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>filename<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.json`</span></span><span class="token punctuation">,</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token keyword keyword-null">null</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">JSONToFile</span><span class="token punctuation">(</span><span class="token punctuation">{</span> test<span class="token punctuation">:</span> <span class="token string">&apos;is passed&apos;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">&apos;testJsonFile&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// writes the object to &apos;testJsonFile.json&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: JSONtoCSV">title: JSONtoCSV</h2>
<p>Converts an array of objects to a comma-separated values (CSV) string that contains only the <code>columns</code> specified.</p>
<ul>
<li>Use <code>Array.prototype.join(delimiter)</code> to combine all the names in <code>columns</code> to create the first row.</li>
<li>Use <code>Array.prototype.map()</code> and <code>Array.prototype.reduce()</code> to create a row for each object. Substitute non-existent values with empty strings and only mapping values in <code>columns</code>.</li>
<li>Use <code>Array.prototype.join(&apos;\n&apos;)</code> to combine all rows into a string.</li>
<li>Omit the third argument, <code>delimiter</code>, to use a default delimiter of <code>&apos;,&apos;</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> JSONtoCSV <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> columns<span class="token punctuation">,</span> delimiter <span class="token operator">=</span> <span class="token string">&apos;,&apos;</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token punctuation">[</span>
columns<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span>delimiter<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token operator">...</span>arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>obj <span class="token operator">=&gt;</span>
columns<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>
<span class="token punctuation">(</span>acc<span class="token punctuation">,</span> key<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token template-string"><span class="token string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>acc<span class="token interpolation-punctuation punctuation">}</span></span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token operator">!</span>acc<span class="token punctuation">.</span>length <span class="token operator">?</span> <span class="token string">&apos;&apos;</span> <span class="token punctuation">:</span> delimiter<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&quot;</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token operator">!</span>obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">?</span> <span class="token string">&apos;&apos;</span> <span class="token punctuation">:</span> obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&quot;`</span></span><span class="token punctuation">,</span>
<span class="token string">&apos;&apos;</span>
<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">JSONtoCSV</span><span class="token punctuation">(</span>
<span class="token punctuation">[</span><span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> b<span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">3</span><span class="token punctuation">,</span> b<span class="token punctuation">:</span> <span class="token number">4</span><span class="token punctuation">,</span> c<span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> b<span class="token punctuation">:</span> <span class="token number">7</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;b&apos;</span><span class="token punctuation">]</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;a,b\n&quot;1&quot;,&quot;2&quot;\n&quot;3&quot;,&quot;4&quot;\n&quot;6&quot;,&quot;&quot;\n&quot;&quot;,&quot;7&quot;&apos;</span>
<span class="token function">JSONtoCSV</span><span class="token punctuation">(</span>
<span class="token punctuation">[</span><span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> b<span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">3</span><span class="token punctuation">,</span> b<span class="token punctuation">:</span> <span class="token number">4</span><span class="token punctuation">,</span> c<span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> b<span class="token punctuation">:</span> <span class="token number">7</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;b&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token string">&apos;;&apos;</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;a;b\n&quot;1&quot;;&quot;2&quot;\n&quot;3&quot;;&quot;4&quot;\n&quot;6&quot;;&quot;&quot;\n&quot;&quot;;&quot;7&quot;&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: RGBToHSB">title: RGBToHSB</h2>
<p>Converts a RGB color tuple to HSB format.</p>
<ul>
<li>Use the <a href="https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB">RGB to HSB conversion formula</a> to convert to the appropriate format.</li>
<li>The range of all input parameters is [0, 255].</li>
<li>The range of the resulting values is H: [0, 360], S: [0, 100], B: [0, 100].</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">RGBToHSB</span> <span class="token operator">=</span> <span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
r <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
g <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
b <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> v <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">,</span>
n <span class="token operator">=</span> v <span class="token operator">-</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> h <span class="token operator">=</span>
n <span class="token operator">===</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token number">0</span> <span class="token punctuation">:</span> n <span class="token operator">&amp;&amp;</span> v <span class="token operator">===</span> r <span class="token operator">?</span> <span class="token punctuation">(</span>g <span class="token operator">-</span> b<span class="token punctuation">)</span> <span class="token operator">/</span> n <span class="token punctuation">:</span> v <span class="token operator">===</span> g <span class="token operator">?</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token punctuation">(</span>b <span class="token operator">-</span> r<span class="token punctuation">)</span> <span class="token operator">/</span> n <span class="token punctuation">:</span> <span class="token number">4</span> <span class="token operator">+</span> <span class="token punctuation">(</span>r <span class="token operator">-</span> g<span class="token punctuation">)</span> <span class="token operator">/</span> n<span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token punctuation">[</span><span class="token number">60</span> <span class="token operator">*</span> <span class="token punctuation">(</span>h <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">?</span> h <span class="token operator">+</span> <span class="token number">6</span> <span class="token punctuation">:</span> h<span class="token punctuation">)</span><span class="token punctuation">,</span> v <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>n <span class="token operator">/</span> v<span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span><span class="token punctuation">,</span> v <span class="token operator">*</span> <span class="token number">100</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">RGBToHSB</span><span class="token punctuation">(</span><span class="token number">252</span><span class="token punctuation">,</span> <span class="token number">111</span><span class="token punctuation">,</span> <span class="token number">48</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [18.529411764705856, 80.95238095238095, 98.82352941176471]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: RGBToHSL">title: RGBToHSL</h2>
<p>Converts a RGB color tuple to HSL format.</p>
<ul>
<li>Use the <a href="https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/">RGB to HSL conversion formula</a> to convert to the appropriate format.</li>
<li>The range of all input parameters is [0, 255].</li>
<li>The range of the resulting values is H: [0, 360], S: [0, 100], L: [0, 100].</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">RGBToHSL</span> <span class="token operator">=</span> <span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
r <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
g <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
b <span class="token operator">/=</span> <span class="token number">255</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> l <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> s <span class="token operator">=</span> l <span class="token operator">-</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> h <span class="token operator">=</span> s
<span class="token operator">?</span> l <span class="token operator">===</span> r
<span class="token operator">?</span> <span class="token punctuation">(</span>g <span class="token operator">-</span> b<span class="token punctuation">)</span> <span class="token operator">/</span> s
<span class="token punctuation">:</span> l <span class="token operator">===</span> g
<span class="token operator">?</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token punctuation">(</span>b <span class="token operator">-</span> r<span class="token punctuation">)</span> <span class="token operator">/</span> s
<span class="token punctuation">:</span> <span class="token number">4</span> <span class="token operator">+</span> <span class="token punctuation">(</span>r <span class="token operator">-</span> g<span class="token punctuation">)</span> <span class="token operator">/</span> s
<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token punctuation">[</span>
<span class="token number">60</span> <span class="token operator">*</span> h <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token number">60</span> <span class="token operator">*</span> h <span class="token operator">+</span> <span class="token number">360</span> <span class="token punctuation">:</span> <span class="token number">60</span> <span class="token operator">*</span> h<span class="token punctuation">,</span>
<span class="token number">100</span> <span class="token operator">*</span> <span class="token punctuation">(</span>s <span class="token operator">?</span> <span class="token punctuation">(</span>l <span class="token operator">&lt;=</span> <span class="token number">0.5</span> <span class="token operator">?</span> s <span class="token operator">/</span> <span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">*</span> l <span class="token operator">-</span> s<span class="token punctuation">)</span> <span class="token punctuation">:</span> s <span class="token operator">/</span> <span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">-</span> <span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">*</span> l <span class="token operator">-</span> s<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span><span class="token number">100</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">*</span> l <span class="token operator">-</span> s<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">RGBToHSL</span><span class="token punctuation">(</span><span class="token number">45</span><span class="token punctuation">,</span> <span class="token number">23</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [21.17647, 60.71428, 10.98039]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: RGBToHex">title: RGBToHex</h2>
<p>Converts the values of RGB components to a hexadecimal color code.</p>
<ul>
<li>Convert given RGB parameters to hexadecimal string using bitwise left-shift operator (<code>&lt;&lt;</code>) and <code>Number.prototype.toString(16)</code>.</li>
<li>Use <code>String.prototype.padStart(6, &apos;0&apos;)</code> to get a 6-digit hexadecimal value.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">RGBToHex</span> <span class="token operator">=</span> <span class="token punctuation">(</span>r<span class="token punctuation">,</span> g<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token punctuation">(</span><span class="token punctuation">(</span>r <span class="token operator">&lt;&lt;</span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token punctuation">(</span>g <span class="token operator">&lt;&lt;</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token operator">+</span> b<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">padStart</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">,</span> <span class="token string">&apos;0&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">RGBToHex</span><span class="token punctuation">(</span><span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">165</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;ffa501&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: URLJoin">title: URLJoin</h2>
<p>Joins all given URL segments together, then normalizes the resulting URL.</p>
<ul>
<li>Use <code>String.prototype.join(&apos;/&apos;)</code> to combine URL segments.</li>
<li>Use a series of <code>String.prototype.replace()</code> calls with various regexps to normalize the resulting URL (remove double slashes, add proper slashes for protocol, remove slashes before parameters, combine parameters with <code>&apos;&amp;&apos;</code> and normalize first parameter delimiter).</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">URLJoin</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
args
<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;/&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/[\/]+/g</span><span class="token punctuation">,</span> <span class="token string">&apos;/&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/^(.+):\//</span><span class="token punctuation">,</span> <span class="token string">&apos;$1://&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/^file:/</span><span class="token punctuation">,</span> <span class="token string">&apos;file:/&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/\/(\?|&amp;|#[^!])/g</span><span class="token punctuation">,</span> <span class="token string">&apos;$1&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/\?/g</span><span class="token punctuation">,</span> <span class="token string">&apos;&amp;&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">&apos;&amp;&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;?&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">URLJoin</span><span class="token punctuation">(</span><span class="token string">&apos;http://www.google.com&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;/b/cd&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;?foo=123&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;?bar=foo&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// &apos;http://www.google.com/a/b/cd?foo=123&amp;bar=foo&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: UUIDGeneratorBrowser">title: UUIDGeneratorBrowser</h2>
<p>Generates a UUID in a browser.</p>
<ul>
<li>Use <code>Crypto.getRandomValues()</code> to generate a UUID, compliant with <a href="https://www.ietf.org/rfc/rfc4122.txt">RFC4122</a> version 4.</li>
<li>Use <code>Number.prototype.toString(16)</code> to convert it to a proper UUID.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">UUIDGeneratorBrowser</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1e7</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">1e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">4e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">8e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">1e11</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/[018]/g</span><span class="token punctuation">,</span> c <span class="token operator">=&gt;</span>
<span class="token punctuation">(</span>
c <span class="token operator">^</span>
<span class="token punctuation">(</span>crypto<span class="token punctuation">.</span><span class="token function">getRandomValues</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Uint8Array</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">&amp;</span> <span class="token punctuation">(</span><span class="token number">15</span> <span class="token operator">&gt;&gt;</span> <span class="token punctuation">(</span>c <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">UUIDGeneratorBrowser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;7982fcfe-5721-4632-bede-6000885be57d&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: UUIDGeneratorNode">title: UUIDGeneratorNode</h2>
<p>Generates a UUID in Node.JS.</p>
<ul>
<li>Use <code>crypto.randomBytes()</code> to generate a UUID, compliant with <a href="https://www.ietf.org/rfc/rfc4122.txt">RFC4122</a> version 4.</li>
<li>Use <code>Number.prototype.toString(16)</code> to convert it to a proper UUID.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> crypto <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&apos;crypto&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">UUIDGeneratorNode</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1e7</span><span class="token punctuation">]</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">1e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">4e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">8e3</span> <span class="token operator">+</span> <span class="token operator">-</span><span class="token number">1e11</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/[018]/g</span><span class="token punctuation">,</span> c <span class="token operator">=&gt;</span>
<span class="token punctuation">(</span>c <span class="token operator">^</span> <span class="token punctuation">(</span>crypto<span class="token punctuation">.</span><span class="token function">randomBytes</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">&amp;</span> <span class="token punctuation">(</span><span class="token number">15</span> <span class="token operator">&gt;&gt;</span> <span class="token punctuation">(</span>c <span class="token operator">/</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">UUIDGeneratorNode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;79c7c136-60ee-40a2-beb2-856f1feabefc&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: accumulate">title: accumulate</h2>
<p>Creates an array of partial sums.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code>, initialized with an empty array accumulator to iterate over <code>nums</code>.</li>
<li>Use <code>Array.prototype.slice(-1)</code>, the spread operator (<code>...</code>) and the unary <code>+</code> operator to add each value to the accumulator array containing the previous sums.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">accumulate</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">...</span>nums<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
nums<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">[</span><span class="token operator">...</span>acc<span class="token punctuation">,</span> n <span class="token operator">+</span> <span class="token operator">+</span>acc<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">accumulate</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 3, 6, 10]</span>
<span class="token function">accumulate</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 3, 6, 10]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addClass">title: addClass</h2>
<p>Adds a class to an HTML element.</p>
<ul>
<li>Use <code>Element.classList</code> and <code>DOMTokenList.add()</code> to add the specified class to the element.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addClass</span> <span class="token operator">=</span> <span class="token punctuation">(</span>el<span class="token punctuation">,</span> className<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> el<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>className<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addClass</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">&apos;p&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">&apos;special&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// The paragraph will now have the &apos;special&apos; class</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addDaysToDate">title: addDaysToDate</h2>
<p>Calculates the date of <code>n</code> days from the given date, returning its string representation.</p>
<ul>
<li>Use <code>new Date()</code> to create a date object from the first argument.</li>
<li>Use <code>Date.prototype.getDate()</code> and <code>Date.prototype.setDate()</code> to add <code>n</code> days to the given date.</li>
<li>Use <code>Date.prototype.toISOString()</code> to return a string in <code>yyyy-mm-dd</code> format.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addDaysToDate</span> <span class="token operator">=</span> <span class="token punctuation">(</span>date<span class="token punctuation">,</span> n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> d <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span>
d<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> d<span class="token punctuation">.</span><span class="token function">toISOString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&apos;T&apos;</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addDaysToDate</span><span class="token punctuation">(</span><span class="token string">&apos;2020-10-15&apos;</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;2020-10-25&apos;</span>
<span class="token function">addDaysToDate</span><span class="token punctuation">(</span><span class="token string">&apos;2020-10-15&apos;</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;2020-10-05&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addEventListenerAll">title: addEventListenerAll</h2>
<p>Attaches an event listener to all the provided targets.</p>
<ul>
<li>Use <code>Array.prototype.forEach()</code> and <code>EventTarget.addEventListener()</code> to attach the provided <code>listener</code> for the given event <code>type</code> to all <code>targets</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addEventListenerAll</span> <span class="token operator">=</span> <span class="token punctuation">(</span>targets<span class="token punctuation">,</span> type<span class="token punctuation">,</span> listener<span class="token punctuation">,</span> options<span class="token punctuation">,</span> useCapture<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
targets<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>target <span class="token operator">=&gt;</span>
target<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> listener<span class="token punctuation">,</span> options<span class="token punctuation">,</span> useCapture<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addEventListenerAll</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">&apos;click&apos;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&apos;Clicked a link&apos;</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Logs &apos;Clicked a link&apos; whenever any anchor element is clicked</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addMinutesToDate">title: addMinutesToDate</h2>
<p>Calculates the date of <code>n</code> minutes from the given date, returning its string representation.</p>
<ul>
<li>Use <code>new Date()</code> to create a date object from the first argument.</li>
<li>Use <code>Date.prototype.getTime()</code> and <code>Date.prototype.setTime()</code> to add <code>n</code> minutes to the given date.</li>
<li>Use <code>Date.prototype.toISOString()</code>, <code>String.prototype.split()</code> and <code>String.prototype.replace()</code> to return a string in <code>yyyy-mm-dd HH:MM:SS</code> format.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addMinutesToDate</span> <span class="token operator">=</span> <span class="token punctuation">(</span>date<span class="token punctuation">,</span> n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> d <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>date<span class="token punctuation">)</span><span class="token punctuation">;</span>
d<span class="token punctuation">.</span><span class="token function">setTime</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> n <span class="token operator">*</span> <span class="token number">60000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> d<span class="token punctuation">.</span><span class="token function">toISOString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&apos;.&apos;</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">&apos;T&apos;</span><span class="token punctuation">,</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addMinutesToDate</span><span class="token punctuation">(</span><span class="token string">&apos;2020-10-19 12:00:00&apos;</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;2020-10-19 12:10:00&apos;</span>
<span class="token function">addMinutesToDate</span><span class="token punctuation">(</span><span class="token string">&apos;2020-10-19&apos;</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;2020-10-18 23:50:00&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addMultipleListeners">title: addMultipleListeners</h2>
<p>Adds multiple event listeners with the same handler to an element.</p>
<ul>
<li>Use <code>Array.prototype.forEach()</code> and <code>EventTarget.addEventListener()</code> to add multiple event listeners with an assigned callback function to an element.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addMultipleListeners</span> <span class="token operator">=</span> <span class="token punctuation">(</span>el<span class="token punctuation">,</span> types<span class="token punctuation">,</span> listener<span class="token punctuation">,</span> options<span class="token punctuation">,</span> useCapture<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
types<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>type <span class="token operator">=&gt;</span>
el<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>type<span class="token punctuation">,</span> listener<span class="token punctuation">,</span> options<span class="token punctuation">,</span> useCapture<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addMultipleListeners</span><span class="token punctuation">(</span>
document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">&apos;.my-element&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">&apos;click&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;mousedown&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&apos;hello!&apos;</span><span class="token punctuation">)</span> <span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addStyles">title: addStyles</h2>
<p>Adds the provided styles to the given element.</p>
<ul>
<li>Use <code>Object.assign()</code> and <code>ElementCSSInlineStyle.style</code> to merge the provided <code>styles</code> object into the style of the given element.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addStyles</span> <span class="token operator">=</span> <span class="token punctuation">(</span>el<span class="token punctuation">,</span> styles<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span>el<span class="token punctuation">.</span>style<span class="token punctuation">,</span> styles<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addStyles</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">&apos;my-element&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
background<span class="token punctuation">:</span> <span class="token string">&apos;red&apos;</span><span class="token punctuation">,</span>
color<span class="token punctuation">:</span> <span class="token string">&apos;#ffff00&apos;</span><span class="token punctuation">,</span>
fontSize<span class="token punctuation">:</span> <span class="token string">&apos;3rem&apos;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: addWeekDays">title: addWeekDays</h2>
<p>Calculates the date after adding the given number of business days.</p>
<ul>
<li>Use <code>Array.from()</code> to construct an array with <code>length</code> equal to the <code>count</code> of business days to be added.</li>
<li>Use <code>Array.prototype.reduce()</code> to iterate over the array, starting from <code>startDate</code> and incrementing, using <code>Date.prototype.getDate()</code> and <code>Date.prototype.setDate()</code>.</li>
<li>If the current <code>date</code> is on a weekend, update it again by adding either one day or two days to make it a weekday.</li>
<li><strong>NOTE:</strong> Does not take official holidays into account.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">addWeekDays</span> <span class="token operator">=</span> <span class="token punctuation">(</span>startDate<span class="token punctuation">,</span> count<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Array<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span><span class="token punctuation">{</span> length<span class="token punctuation">:</span> count <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>date <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
date <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">6</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span>
date <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">6</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> date<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> startDate<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">addWeekDays</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">&apos;Oct 09, 2020&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Oct 16, 2020&apos;</span>
<span class="token function">addWeekDays</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">&apos;Oct 12, 2020&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Oct 19, 2020&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: all">title: all</h2>
<p>Checks if the provided predicate function returns <code>true</code> for all elements in a collection.</p>
<ul>
<li>Use <code>Array.prototype.every()</code> to test if all elements in the collection return <code>true</code> based on <code>fn</code>.</li>
<li>Omit the second argument, <code>fn</code>, to use <code>Boolean</code> as a default.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">all</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn <span class="token operator">=</span> Boolean<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> x <span class="token operator">=&gt;</span> x <span class="token operator">&gt;</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: allEqual">title: allEqual</h2>
<p>Checks if all elements in an array are equal.</p>
<ul>
<li>Use <code>Array.prototype.every()</code> to check if all the elements of the array are the same as the first one.</li>
<li>Elements in the array are compared using the strict comparison operator, which does not account for <code>NaN</code> self-inequality.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">allEqual</span> <span class="token operator">=</span> arr <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span>val <span class="token operator">=&gt;</span> val <span class="token operator">===</span> arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">allEqual</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token function">allEqual</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: allEqualBy">title: allEqualBy</h2>
<p>Checks if all elements in an array are equal, based on the provided mapping function.</p>
<ul>
<li>Apply <code>fn</code> to the first element of <code>arr</code>.</li>
<li>Use <code>Array.prototype.every()</code> to check if <code>fn</code> returns the same value for all elements in the array as it did for the first one.</li>
<li>Elements in the array are compared using the strict comparison operator, which does not account for <code>NaN</code> self-inequality.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">allEqualBy</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> eql <span class="token operator">=</span> <span class="token function">fn</span><span class="token punctuation">(</span>arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> arr<span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span>val <span class="token operator">=&gt;</span> <span class="token function">fn</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token operator">===</span> eql<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">allEqualBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span>round<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">allEqualBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1.1</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">,</span> <span class="token number">1.6</span><span class="token punctuation">]</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span>round<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: allUnique">title: allUnique</h2>
<p>Checks if all elements in an array are unique.</p>
<ul>
<li>Create a new <code>Set</code> from the mapped values to keep only unique occurrences.</li>
<li>Use <code>Array.prototype.length</code> and <code>Set.prototype.size</code> to compare the length of the unique values to the original array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">allUnique</span> <span class="token operator">=</span> arr <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">.</span>size<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">allUnique</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">allUnique</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: allUniqueBy">title: allUniqueBy</h2>
<p>Checks if all elements in an array are unique, based on the provided mapping function.</p>
<ul>
<li>Use <code>Array.prototype.map()</code> to apply <code>fn</code> to all elements in <code>arr</code>.</li>
<li>Create a new <code>Set</code> from the mapped values to keep only unique occurrences.</li>
<li>Use <code>Array.prototype.length</code> and <code>Set.prototype.size</code> to compare the length of the unique mapped values to the original array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">allUniqueBy</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>size<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">allUniqueBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">2.4</span><span class="token punctuation">,</span> <span class="token number">2.9</span><span class="token punctuation">]</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span>round<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">allUniqueBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">2.3</span><span class="token punctuation">,</span> <span class="token number">2.4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span>round<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: and&lt;br&gt;
unlisted: true">title: and<br>
unlisted: true</h2>
<p>Checks if both arguments are <code>true</code>.</p>
<ul>
<li>Use the logical and (<code>&amp;&amp;</code>) operator on the two given values.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">and</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> a <span class="token operator">&amp;&amp;</span> b<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">and</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">and</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token function">and</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: any">title: any</h2>
<p>Checks if the provided predicate function returns <code>true</code> for at least one element in a collection.</p>
<ul>
<li>Use <code>Array.prototype.some()</code> to test if any elements in the collection return <code>true</code> based on <code>fn</code>.</li>
<li>Omit the second argument, <code>fn</code>, to use <code>Boolean</code> as a default.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">any</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn <span class="token operator">=</span> Boolean<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span><span class="token function">some</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">any</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> x <span class="token operator">=&gt;</span> x <span class="token operator">&gt;=</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">any</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: aperture">title: aperture</h2>
<p>Creates an array of <code>n</code>-tuples of consecutive elements.</p>
<ul>
<li>Use <code>Array.prototype.slice()</code> and <code>Array.prototype.map()</code> to create an array of appropriate length.</li>
<li>Populate the array with <code>n</code>-tuples of consecutive elements from <code>arr</code>.</li>
<li>If <code>n</code> is greater than the length of <code>arr</code>, return an empty array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">aperture</span> <span class="token operator">=</span> <span class="token punctuation">(</span>n<span class="token punctuation">,</span> arr<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
n <span class="token operator">&gt;</span> arr<span class="token punctuation">.</span>length
<span class="token operator">?</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
<span class="token punctuation">:</span> arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>v<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> i <span class="token operator">+</span> n<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">aperture</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[1, 2], [2, 3], [3, 4]]</span>
<span class="token function">aperture</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[1, 2, 3], [2, 3, 4]]</span>
<span class="token function">aperture</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// []</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: approximatelyEqual">title: approximatelyEqual</h2>
<p>Checks if two numbers are approximately equal to each other.</p>
<ul>
<li>Use <code>Math.abs()</code> to compare the absolute difference of the two values to <code>epsilon</code>.</li>
<li>Omit the third argument, <code>epsilon</code>, to use a default value of <code>0.001</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">approximatelyEqual</span> <span class="token operator">=</span> <span class="token punctuation">(</span>v1<span class="token punctuation">,</span> v2<span class="token punctuation">,</span> epsilon <span class="token operator">=</span> <span class="token number">0.001</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Math<span class="token punctuation">.</span><span class="token function">abs</span><span class="token punctuation">(</span>v1 <span class="token operator">-</span> v2<span class="token punctuation">)</span> <span class="token operator">&lt;</span> epsilon<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">approximatelyEqual</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token constant">PI</span> <span class="token operator">/</span> <span class="token number">2.0</span><span class="token punctuation">,</span> <span class="token number">1.5708</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: arithmeticProgression">title: arithmeticProgression</h2>
<p>Creates an array of numbers in the arithmetic progression, starting with the given positive integer and up to the specified limit.</p>
<ul>
<li>Use <code>Array.from()</code> to create an array of the desired length, <code>lim/n</code>. Use a map function to fill it with the desired values in the given range.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">arithmeticProgression</span> <span class="token operator">=</span> <span class="token punctuation">(</span>n<span class="token punctuation">,</span> lim<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Array<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span><span class="token punctuation">{</span> length<span class="token punctuation">:</span> Math<span class="token punctuation">.</span><span class="token function">ceil</span><span class="token punctuation">(</span>lim <span class="token operator">/</span> n<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>_<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">*</span> n <span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">arithmeticProgression</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">25</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [5, 10, 15, 20, 25]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: arrayToCSV">title: arrayToCSV</h2>
<p>Converts a 2D array to a comma-separated values (CSV) string.</p>
<ul>
<li>Use <code>Array.prototype.map()</code> and <code>Array.prototype.join(delimiter)</code> to combine individual 1D arrays (rows) into strings.</li>
<li>Use <code>Array.prototype.join(&apos;\n&apos;)</code> to combine all rows into a CSV string, separating each row with a newline.</li>
<li>Omit the second argument, <code>delimiter</code>, to use a default delimiter of <code>,</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> arrayToCSV <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> delimiter <span class="token operator">=</span> <span class="token string">&apos;,&apos;</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>v <span class="token operator">=&gt;</span>
v<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>x <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token function">isNaN</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token template-string"><span class="token string">`&quot;</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>x<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/&quot;/g</span><span class="token punctuation">,</span> <span class="token string">&apos;&quot;&quot;&apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&quot;`</span></span> <span class="token punctuation">:</span> x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span>delimiter<span class="token punctuation">)</span>
<span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;\n&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">arrayToCSV</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;b&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;c&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;d&apos;</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;&quot;a&quot;,&quot;b&quot;\n&quot;c&quot;,&quot;d&quot;&apos;</span>
<span class="token function">arrayToCSV</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;b&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;c&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;d&apos;</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">&apos;;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;&quot;a&quot;;&quot;b&quot;\n&quot;c&quot;;&quot;d&quot;&apos;</span>
<span class="token function">arrayToCSV</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;&quot;b&quot; great&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;c&apos;</span><span class="token punctuation">,</span> <span class="token number">3.1415</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// &apos;&quot;a&quot;,&quot;&quot;&quot;b&quot;&quot; great&quot;\n&quot;c&quot;,3.1415&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: arrayToHTMLList">title: arrayToHTMLList</h2>
<p>Converts the given array elements into <code>&lt;li&gt;</code> tags and appends them to the list of the given id.</p>
<ul>
<li>Use <code>Array.prototype.map()</code> and <code>Document.querySelector()</code> to create a list of html tags.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">arrayToHTMLList</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> listID<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token template-string"><span class="token string">`#</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>listID<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">+=</span> arr
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>item <span class="token operator">=&gt;</span> <span class="token template-string"><span class="token string">`&lt;li&gt;</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>item<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">&lt;/li&gt;`</span></span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">arrayToHTMLList</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">&apos;item 1&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;item 2&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">&apos;myListID&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: ary">title: ary</h2>
<p>Creates a function that accepts up to <code>n</code> arguments, ignoring any additional arguments.</p>
<ul>
<li>Call the provided function, <code>fn</code>, with up to <code>n</code> arguments, using <code>Array.prototype.slice(0, n)</code> and the spread operator (<code>...</code>).</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">ary</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> firstTwoMax <span class="token operator">=</span> <span class="token function">ary</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span>max<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token string">&apos;a&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>x <span class="token operator">=&gt;</span> <span class="token function">firstTwoMax</span><span class="token punctuation">(</span><span class="token operator">...</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [6, 6, 10]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: assertValidKeys">title: assertValidKeys</h2>
<p>Validates all keys in an object match the given <code>keys</code>.</p>
<ul>
<li>Use <code>Object.keys()</code> to get the keys of the given object, <code>obj</code>.</li>
<li>Use <code>Array.prototype.every()</code> and <code>Array.prototype.includes()</code> to validate that each key in the object is specified in the <code>keys</code> array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">assertValidKeys</span> <span class="token operator">=</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> keys<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span>key <span class="token operator">=&gt;</span> keys<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">assertValidKeys</span><span class="token punctuation">(</span><span class="token punctuation">{</span> id<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">&apos;apple&apos;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;id&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;name&apos;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">assertValidKeys</span><span class="token punctuation">(</span><span class="token punctuation">{</span> id<span class="token punctuation">:</span> <span class="token number">10</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">&apos;apple&apos;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;id&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;type&apos;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: atob">title: atob</h2>
<p>Decodes a string of data which has been encoded using base-64 encoding.</p>
<ul>
<li>Create a <code>Buffer</code> for the given string with base-64 encoding and use <code>Buffer.toString(&apos;binary&apos;)</code> to return the decoded string.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">atob</span> <span class="token operator">=</span> str <span class="token operator">=&gt;</span> Buffer<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span>str<span class="token punctuation">,</span> <span class="token string">&apos;base64&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token string">&apos;binary&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">atob</span><span class="token punctuation">(</span><span class="token string">&apos;Zm9vYmFy&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;foobar&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: attempt">title: attempt</h2>
<p>Attempts to invoke a function with the provided arguments, returning either the result or the caught error object.</p>
<ul>
<li>Use a <code>try... catch</code> block to return either the result of the function or an appropriate error.</li>
<li>If the caught object is not an <code>Error</code>, use it to create a new <code>Error</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">attempt</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-try">try</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword keyword-catch">catch</span> <span class="token punctuation">(</span><span class="token class-name">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> e <span class="token keyword keyword-instanceof">instanceof</span> <span class="token class-name">Error</span> <span class="token operator">?</span> e <span class="token punctuation">:</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-let">let</span> elements <span class="token operator">=</span> <span class="token function">attempt</span><span class="token punctuation">(</span><span class="token keyword keyword-function">function</span><span class="token punctuation">(</span>selector<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> document<span class="token punctuation">.</span><span class="token function">querySelectorAll</span><span class="token punctuation">(</span>selector<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">&apos;&gt;_&gt;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>elements <span class="token keyword keyword-instanceof">instanceof</span> <span class="token class-name">Error</span><span class="token punctuation">)</span> elements <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// elements = []</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: average">title: average</h2>
<p>Calculates the average of two or more numbers.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code> to add each value to an accumulator, initialized with a value of <code>0</code>.</li>
<li>Divide the resulting array by its length.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">average</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">...</span>nums<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
nums<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> val<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> acc <span class="token operator">+</span> val<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">/</span> nums<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">average</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span>
<span class="token function">average</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: averageBy">title: averageBy</h2>
<p>Calculates the average of an array, after mapping each element to a value using the provided function.</p>
<ul>
<li>Use <code>Array.prototype.map()</code> to map each element to the value returned by <code>fn</code>.</li>
<li>Use <code>Array.prototype.reduce()</code> to add each value to an accumulator, initialized with a value of <code>0</code>.</li>
<li>Divide the resulting array by its length.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">averageBy</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword keyword-typeof">typeof</span> fn <span class="token operator">===</span> <span class="token string">&apos;function&apos;</span> <span class="token operator">?</span> fn <span class="token punctuation">:</span> val <span class="token operator">=&gt;</span> val<span class="token punctuation">[</span>fn<span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> val<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> acc <span class="token operator">+</span> val<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">/</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">averageBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">4</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">8</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span> o <span class="token operator">=&gt;</span> o<span class="token punctuation">.</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span>
<span class="token function">averageBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">4</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">8</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> n<span class="token punctuation">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">&apos;n&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 5</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bifurcate">title: bifurcate</h2>
<p>Splits values into two groups, based on the result of the given <code>filter</code> array.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code> and <code>Array.prototype.push()</code> to add elements to groups, based on <code>filter</code>.</li>
<li>If <code>filter</code> has a truthy value for any element, add it to the first group, otherwise add it to the second group.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bifurcate</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> filter<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> val<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>acc<span class="token punctuation">[</span>filter<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">?</span> <span class="token number">0</span> <span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">,</span> acc<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">bifurcate</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">&apos;beep&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;boop&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;foo&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;bar&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [ [&apos;beep&apos;, &apos;boop&apos;, &apos;bar&apos;], [&apos;foo&apos;] ]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bifurcateBy">title: bifurcateBy</h2>
<p>Splits values into two groups, based on the result of the given filtering function.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code> and <code>Array.prototype.push()</code> to add elements to groups, based on the value returned by <code>fn</code> for each element.</li>
<li>If <code>fn</code> returns a truthy value for any element, add it to the first group, otherwise add it to the second group.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bifurcateBy</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> val<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>acc<span class="token punctuation">[</span><span class="token function">fn</span><span class="token punctuation">(</span>val<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token number">0</span> <span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">,</span> acc<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">bifurcateBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">&apos;beep&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;boop&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;foo&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;bar&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> x <span class="token operator">=&gt;</span> x<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token string">&apos;b&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [ [&apos;beep&apos;, &apos;boop&apos;, &apos;bar&apos;], [&apos;foo&apos;] ]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: binary">title: binary</h2>
<p>Creates a function that accepts up to two arguments, ignoring any additional arguments.</p>
<ul>
<li>Call the provided function, <code>fn</code>, with the first two arguments given.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">binary</span> <span class="token operator">=</span> fn <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">fn</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token punctuation">[</span><span class="token string">&apos;2&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;1&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;0&apos;</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token function">binary</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span>max<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [2, 1, 2]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: binarySearch">title: binarySearch</h2>
<p>Finds the index of a given element in a sorted array using the binary search algorithm.</p>
<ul>
<li>Declare the left and right search boundaries, <code>l</code> and <code>r</code>, initialized to <code>0</code> and the <code>length</code> of the array respectively.</li>
<li>Use a <code>while</code> loop to repeatedly narrow down the search subarray, using <code>Math.floor()</code> to cut it in half.</li>
<li>Return the index of the element if found, otherwise return <code>-1</code>.</li>
<li><strong>Note:</strong> Does not account for duplicate values in the array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">binarySearch</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> item<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> l <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span>
r <span class="token operator">=</span> arr<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword keyword-while">while</span> <span class="token punctuation">(</span>l <span class="token operator">&lt;=</span> r<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> mid <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span><span class="token punctuation">(</span>l <span class="token operator">+</span> r<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> guess <span class="token operator">=</span> arr<span class="token punctuation">[</span>mid<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>guess <span class="token operator">===</span> item<span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> mid<span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>guess <span class="token operator">&gt;</span> item<span class="token punctuation">)</span> r <span class="token operator">=</span> mid <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword keyword-else">else</span> l <span class="token operator">=</span> mid <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword keyword-return">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">binarySearch</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span>
<span class="token function">binarySearch</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span>
<span class="token function">binarySearch</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -1</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bind">title: bind</h2>
<p>Creates a function that invokes <code>fn</code> with a given context, optionally prepending any additional supplied parameters to the arguments.</p>
<ul>
<li>Return a <code>function</code> that uses <code>Function.prototype.apply()</code> to apply the given <code>context</code> to <code>fn</code>.</li>
<li>Use the spread operator (<code>...</code>) to prepend any additional supplied parameters to the arguments.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bind</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> context<span class="token punctuation">,</span> <span class="token operator">...</span>boundArgs<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
fn<span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token operator">...</span>boundArgs<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-function">function</span> <span class="token function">greet</span><span class="token punctuation">(</span>greeting<span class="token punctuation">,</span> punctuation<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> greeting <span class="token operator">+</span> <span class="token string">&apos; &apos;</span> <span class="token operator">+</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>user <span class="token operator">+</span> punctuation<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword keyword-const">const</span> freddy <span class="token operator">=</span> <span class="token punctuation">{</span> user<span class="token punctuation">:</span> <span class="token string">&apos;fred&apos;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> freddyBound <span class="token operator">=</span> <span class="token function">bind</span><span class="token punctuation">(</span>greet<span class="token punctuation">,</span> freddy<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">freddyBound</span><span class="token punctuation">(</span><span class="token string">&apos;hi&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;!&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;hi fred!&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bindAll">title: bindAll</h2>
<p>Binds methods of an object to the object itself, overwriting the existing method.</p>
<ul>
<li>Use <code>Array.prototype.forEach()</code> to iterate over the given <code>fns</code>.</li>
<li>Return a function for each one, using <code>Function.prototype.apply()</code> to apply the given context (<code>obj</code>) to <code>fn</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bindAll</span> <span class="token operator">=</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token operator">...</span>fns<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
fns<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>
fn <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
<span class="token punctuation">(</span>f <span class="token operator">=</span> obj<span class="token punctuation">[</span>fn<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span>obj<span class="token punctuation">[</span>fn<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword keyword-function">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> f<span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-let">let</span> view <span class="token operator">=</span> <span class="token punctuation">{</span>
label<span class="token punctuation">:</span> <span class="token string">&apos;docs&apos;</span><span class="token punctuation">,</span>
click<span class="token punctuation">:</span> <span class="token keyword keyword-function">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&apos;clicked &apos;</span> <span class="token operator">+</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>label<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token function">bindAll</span><span class="token punctuation">(</span>view<span class="token punctuation">,</span> <span class="token string">&apos;click&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">&apos;click&apos;</span><span class="token punctuation">,</span> view<span class="token punctuation">.</span>click<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Log &apos;clicked docs&apos; when clicked.</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bindKey">title: bindKey</h2>
<p>Creates a function that invokes the method at a given key of an object, optionally prepending any additional supplied parameters to the arguments.</p>
<ul>
<li>Return a <code>function</code> that uses <code>Function.prototype.apply()</code> to bind <code>context[fn]</code> to <code>context</code>.</li>
<li>Use the spread operator (<code>...</code>) to prepend any additional supplied parameters to the arguments.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bindKey</span> <span class="token operator">=</span> <span class="token punctuation">(</span>context<span class="token punctuation">,</span> fn<span class="token punctuation">,</span> <span class="token operator">...</span>boundArgs<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
context<span class="token punctuation">[</span>fn<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token operator">...</span>boundArgs<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> freddy <span class="token operator">=</span> <span class="token punctuation">{</span>
user<span class="token punctuation">:</span> <span class="token string">&apos;fred&apos;</span><span class="token punctuation">,</span>
greet<span class="token punctuation">:</span> <span class="token keyword keyword-function">function</span><span class="token punctuation">(</span>greeting<span class="token punctuation">,</span> punctuation<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> greeting <span class="token operator">+</span> <span class="token string">&apos; &apos;</span> <span class="token operator">+</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>user <span class="token operator">+</span> punctuation<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> freddyBound <span class="token operator">=</span> <span class="token function">bindKey</span><span class="token punctuation">(</span>freddy<span class="token punctuation">,</span> <span class="token string">&apos;greet&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">freddyBound</span><span class="token punctuation">(</span><span class="token string">&apos;hi&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;!&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;hi fred!&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: binomialCoefficient">title: binomialCoefficient</h2>
<p>Calculates the number of ways to choose <code>k</code> items from <code>n</code> items without repetition and without order.</p>
<ul>
<li>Use <code>Number.isNaN()</code> to check if any of the two values is <code>NaN</code>.</li>
<li>Check if <code>k</code> is less than <code>0</code>, greater than or equal to <code>n</code>, equal to <code>1</code> or <code>n - 1</code> and return the appropriate result.</li>
<li>Check if <code>n - k</code> is less than <code>k</code> and switch their values accordingly.</li>
<li>Loop from <code>2</code> through <code>k</code> and calculate the binomial coefficient.</li>
<li>Use <code>Math.round()</code> to account for rounding errors in the calculation.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">binomialCoefficient</span> <span class="token operator">=</span> <span class="token punctuation">(</span>n<span class="token punctuation">,</span> k<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">||</span> Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> <span class="token number">NaN</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>k <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">||</span> k <span class="token operator">&gt;</span> n<span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>k <span class="token operator">===</span> <span class="token number">0</span> <span class="token operator">||</span> k <span class="token operator">===</span> n<span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>k <span class="token operator">===</span> <span class="token number">1</span> <span class="token operator">||</span> k <span class="token operator">===</span> n <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> n<span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>n <span class="token operator">-</span> k <span class="token operator">&lt;</span> k<span class="token punctuation">)</span> k <span class="token operator">=</span> n <span class="token operator">-</span> k<span class="token punctuation">;</span>
<span class="token keyword keyword-let">let</span> res <span class="token operator">=</span> n<span class="token punctuation">;</span>
<span class="token keyword keyword-for">for</span> <span class="token punctuation">(</span><span class="token keyword keyword-let">let</span> j <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> j <span class="token operator">&lt;=</span> k<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> res <span class="token operator">*=</span> <span class="token punctuation">(</span>n <span class="token operator">-</span> j <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">/</span> j<span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> Math<span class="token punctuation">.</span><span class="token function">round</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">binomialCoefficient</span><span class="token punctuation">(</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 28</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: both&lt;br&gt;
unlisted: true">title: both<br>
unlisted: true</h2>
<p>Checks if both of the given functions return <code>true</code> for a given set of arguments.</p>
<ul>
<li>Use the logical and (<code>&amp;&amp;</code>) operator on the result of calling the two functions with the supplied <code>args</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">both</span> <span class="token operator">=</span> <span class="token punctuation">(</span>f<span class="token punctuation">,</span> g<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token function">g</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">isEven</span> <span class="token operator">=</span> num <span class="token operator">=&gt;</span> num <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">isPositive</span> <span class="token operator">=</span> num <span class="token operator">=&gt;</span> num <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> isPositiveEven <span class="token operator">=</span> <span class="token function">both</span><span class="token punctuation">(</span>isEven<span class="token punctuation">,</span> isPositive<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">isPositiveEven</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">isPositiveEven</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</pre><p><a href="https://www.wappalyzer.com/technologies/widgets/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Widgets</a>&#xA0;<br>
chrome-extension://gppongmhjkpfnbhagpmjfkannfbllamg/images/icons/Moat.svg<br>
chrome-extension://gppongmhjkpfnbhagpmjfkannfbllamg/images/icons/Facebook.svg<br>
<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Facebook.svg" alt></p>
<p>Facebook](<a href="https://www.wappalyzer.com/technologies/widgets/facebook/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/widgets/facebook/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\AddThis.svg" alt></p>
<p>AddThis](<a href="https://www.wappalyzer.com/technologies/widgets/addthis/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/widgets/addthis/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/analytics/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Analytics</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Moat.svg" alt></p>
<p>Moat](<a href="https://www.wappalyzer.com/technologies/analytics/moat/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/analytics/moat/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Google%20Analytics.svg" alt></p>
<p>Google Analytics](<a href="https://www.wappalyzer.com/technologies/analytics/google-analytics/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/analytics/google-analytics/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Google.svg" alt></p>
<p>Google Ads Conversion Tracking](<a href="https://www.wappalyzer.com/technologies/analytics/google-ads-conversion-tracking/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/analytics/google-ads-conversion-tracking/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/javascript-frameworks/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">JavaScript frameworks</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\React.png" alt></p>
<p>React](<a href="https://www.wappalyzer.com/technologies/javascript-frameworks/react/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/javascript-frameworks/react/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Gatsby.svg" alt></p>
<p>Gatsby2.25.4](<a href="https://www.wappalyzer.com/technologies/javascript-frameworks/gatsby/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/javascript-frameworks/gatsby/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/font-scripts/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Font scripts</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Google%20Font%20API.png" alt></p>
<p>Google Font API](<a href="https://www.wappalyzer.com/technologies/font-scripts/google-font-api/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/font-scripts/google-font-api/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/miscellaneous/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Miscellaneous</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\webpack.svg" alt></p>
<p>webpack](<a href="https://www.wappalyzer.com/technologies/miscellaneous/webpack/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/miscellaneous/webpack/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Prism.svg" alt></p>
<p>Prism](<a href="https://www.wappalyzer.com/technologies/miscellaneous/prism/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/miscellaneous/prism/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/cdn/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">CDN</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Unpkg.png" alt></p>
<p>Unpkg](<a href="https://www.wappalyzer.com/technologies/cdn/unpkg/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/cdn/unpkg/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\jsdelivr-icon.svg" alt></p>
<p>jsDelivr](<a href="https://www.wappalyzer.com/technologies/cdn/jsdelivr/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/cdn/jsdelivr/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\jQuery.svg" alt></p>
<p>jQuery CDN](<a href="https://www.wappalyzer.com/technologies/cdn/jquery-cdn/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/cdn/jquery-cdn/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Netlify.svg" alt></p>
<p>Netlify](<a href="https://www.wappalyzer.com/technologies/cdn/netlify/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/cdn/netlify/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/marketing-automation/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Marketing automation</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\mailchimp.svg" alt></p>
<p>MailChimp](<a href="https://www.wappalyzer.com/technologies/marketing-automation/mailchimp/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/marketing-automation/mailchimp/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/advertising/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Advertising</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Google%20AdSense.svg" alt></p>
<p>Google AdSense](<a href="https://www.wappalyzer.com/technologies/advertising/google-adsense/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/advertising/google-adsense/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/tag-managers/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Tag managers</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Google%20Tag%20Manager.svg" alt></p>
<p>Google Tag Manager](<a href="https://www.wappalyzer.com/technologies/tag-managers/google-tag-manager/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/tag-managers/google-tag-manager/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/live-chat/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Live chat</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Smartsupp.svg" alt></p>
<p>Smartsupp1](<a href="https://www.wappalyzer.com/technologies/live-chat/smartsupp/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/live-chat/smartsupp/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\LiveChat.png" alt></p>
<p>LiveChat](<a href="https://www.wappalyzer.com/technologies/live-chat/livechat/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/live-chat/livechat/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/static-site-generator/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Static site generators</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Gatsby.svg" alt></p>
<p>Gatsby2.25.4](<a href="https://www.wappalyzer.com/technologies/static-site-generator/gatsby/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/static-site-generator/gatsby/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/javascript-libraries/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">JavaScript libraries</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Lo-dash.png" alt></p>
<p>Lodash4.17.11](<a href="https://www.wappalyzer.com/technologies/javascript-libraries/lodash/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/javascript-libraries/lodash/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Dojo.png" alt></p>
<p>Dojo1](<a href="https://www.wappalyzer.com/technologies/javascript-libraries/dojo/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/javascript-libraries/dojo/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\core-js.png" alt></p>
<p>core-js3.10.2](<a href="https://www.wappalyzer.com/technologies/javascript-libraries/core-js/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/javascript-libraries/core-js/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\jQuery.svg" alt></p>
<p>jQuery3.1.1](<a href="https://www.wappalyzer.com/technologies/javascript-libraries/jquery/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/javascript-libraries/jquery/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/paas/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">PaaS</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Netlify.svg" alt></p>
<p>Netlify](<a href="https://www.wappalyzer.com/technologies/paas/netlify/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/paas/netlify/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/ui-frameworks/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">UI frameworks</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Bootstrap.svg" alt></p>
<p>Bootstrap5.1.1](<a href="https://www.wappalyzer.com/technologies/ui-frameworks/bootstrap/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/ui-frameworks/bootstrap/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/authentication/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Authentication</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Facebook.svg" alt></p>
<p>Facebook Login](<a href="https://www.wappalyzer.com/technologies/authentication/facebook-login/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/authentication/facebook-login/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/email/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Email</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\mailchimp.svg" alt></p>
<p>MailChimp](<a href="https://www.wappalyzer.com/technologies/email/mailchimp/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/email/mailchimp/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<p><a href="https://www.wappalyzer.com/technologies/retargeting/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">Retargeting</a></p>
<p>[<img src="file:///C:\Users\bryan\Downloads\30-seconds-of-code-snippets\chrome-extension:\gppongmhjkpfnbhagpmjfkannfbllamg\images\icons\Google%20Tag%20Manager.svg" alt></p>
<p>Google Remarketing Tag](<a href="https://www.wappalyzer.com/technologies/retargeting/google-remarketing-tag/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer">https://www.wappalyzer.com/technologies/retargeting/google-remarketing-tag/?utm_source=popup&amp;utm_medium=extension&amp;utm_campaign=wappalyzer</a>)</p>
<hr>
<h2 ebook-toc-level-2 heading="title: btoa">title: btoa</h2>
<p>Creates a base-64 encoded ASCII string from a String object in which each character in the string is treated as a byte of binary data.</p>
<ul>
<li>Create a <code>Buffer</code> for the given string with binary encoding and use <code>Buffer.toString(&apos;base64&apos;)</code> to return the encoded string.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">btoa</span> <span class="token operator">=</span> str <span class="token operator">=&gt;</span> Buffer<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span>str<span class="token punctuation">,</span> <span class="token string">&apos;binary&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token string">&apos;base64&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">btoa</span><span class="token punctuation">(</span><span class="token string">&apos;foobar&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Zm9vYmFy&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bubbleSort">title: bubbleSort</h2>
<p>Sorts an array of numbers, using the bubble sort algorithm.</p>
<ul>
<li>Declare a variable, <code>swapped</code>, that indicates if any values were swapped during the current iteration.</li>
<li>Use the spread operator (<code>...</code>) to clone the original array, <code>arr</code>.</li>
<li>Use a <code>for</code> loop to iterate over the elements of the cloned array, terminating before the last element.</li>
<li>Use a nested <code>for</code> loop to iterate over the segment of the array between <code>0</code> and <code>i</code>, swapping any adjacent out of order elements and setting <code>swapped</code> to <code>true</code>.</li>
<li>If <code>swapped</code> is <code>false</code> after an iteration, no more changes are needed, so the cloned array is returned.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bubbleSort</span> <span class="token operator">=</span> arr <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> swapped <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> a <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>arr<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword keyword-for">for</span> <span class="token punctuation">(</span><span class="token keyword keyword-let">let</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> a<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
swapped <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token keyword keyword-for">for</span> <span class="token punctuation">(</span><span class="token keyword keyword-let">let</span> j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator">&lt;</span> a<span class="token punctuation">.</span>length <span class="token operator">-</span> i<span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>a<span class="token punctuation">[</span>j <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">&lt;</span> a<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token punctuation">[</span>a<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">,</span> a<span class="token punctuation">[</span>j <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span>a<span class="token punctuation">[</span>j <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> a<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
swapped <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>swapped<span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> a<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword keyword-return">return</span> a<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">bubbleSort</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 2, 3, 4]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: bucketSort">title: bucketSort</h2>
<p>Sorts an array of numbers, using the bucket sort algorithm.</p>
<ul>
<li>Use <code>Math.min(),</code> <code>Math.max()</code> and the spread operator (<code>...</code>) to find the minimum and maximum values of the given array.</li>
<li>Use <code>Array.from()</code> and <code>Math.floor()</code> to create the appropriate number of <code>buckets</code> (empty arrays).</li>
<li>Use <code>Array.prototype.forEach()</code> to populate each bucket with the appropriate elements from the array.</li>
<li>Use <code>Array.prototype.reduce()</code>, the spread operator (<code>...</code>) and <code>Array.prototype.sort()</code> to sort each bucket and append it to the result.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">bucketSort</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> size <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> min <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span><span class="token operator">...</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> max <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token operator">...</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> buckets <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span>
<span class="token punctuation">{</span> length<span class="token punctuation">:</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span><span class="token punctuation">(</span>max <span class="token operator">-</span> min<span class="token punctuation">)</span> <span class="token operator">/</span> size<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>val <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
buckets<span class="token punctuation">[</span>Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span><span class="token punctuation">(</span>val <span class="token operator">-</span> min<span class="token punctuation">)</span> <span class="token operator">/</span> size<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> buckets<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">[</span><span class="token operator">...</span>acc<span class="token punctuation">,</span> <span class="token operator">...</span>b<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> a <span class="token operator">-</span> b<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">bucketSort</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 3, 4, 6]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: byteSize">title: byteSize</h2>
<p>Returns the length of a string in bytes.</p>
<ul>
<li>Convert a given string to a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob"><code>Blob</code> Object</a>.</li>
<li>Use <code>Blob.size</code> to get the length of the string in bytes.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">byteSize</span> <span class="token operator">=</span> str <span class="token operator">=&gt;</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Blob</span><span class="token punctuation">(</span><span class="token punctuation">[</span>str<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span>size<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">byteSize</span><span class="token punctuation">(</span><span class="token string">&apos;&#x1F600;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span>
<span class="token function">byteSize</span><span class="token punctuation">(</span><span class="token string">&apos;Hello World&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 11</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: caesarCipher">title: caesarCipher</h2>
<p>Encrypts or decrypts a given string using the Caesar cipher.</p>
<ul>
<li>Use the modulo (<code>%</code>) operator and the ternary operator (<code>?</code>) to calculate the correct encryption/decryption key.</li>
<li>Use the spread operator (<code>...</code>) and <code>Array.prototype.map()</code> to iterate over the letters of the given string.</li>
<li>Use <code>String.prototype.charCodeAt()</code> and <code>String.fromCharCode()</code> to convert each letter appropriately, ignoring special characters, spaces etc.</li>
<li>Use <code>Array.prototype.join()</code> to combine all the letters into a string.</li>
<li>Pass <code>true</code> to the last parameter, <code>decrypt</code>, to decrypt an encrypted string.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">caesarCipher</span> <span class="token operator">=</span> <span class="token punctuation">(</span>str<span class="token punctuation">,</span> shift<span class="token punctuation">,</span> decrypt <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> s <span class="token operator">=</span> decrypt <span class="token operator">?</span> <span class="token punctuation">(</span><span class="token number">26</span> <span class="token operator">-</span> shift<span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">26</span> <span class="token punctuation">:</span> shift<span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> n <span class="token operator">=</span> s <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token operator">?</span> s <span class="token punctuation">:</span> <span class="token number">26</span> <span class="token operator">+</span> <span class="token punctuation">(</span>s <span class="token operator">%</span> <span class="token number">26</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token punctuation">[</span><span class="token operator">...</span>str<span class="token punctuation">]</span>
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>l<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> c <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">charCodeAt</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>c <span class="token operator">&gt;=</span> <span class="token number">65</span> <span class="token operator">&amp;&amp;</span> c <span class="token operator">&lt;=</span> <span class="token number">90</span><span class="token punctuation">)</span>
<span class="token keyword keyword-return">return</span> String<span class="token punctuation">.</span><span class="token function">fromCharCode</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>c <span class="token operator">-</span> <span class="token number">65</span> <span class="token operator">+</span> n<span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">26</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">65</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>c <span class="token operator">&gt;=</span> <span class="token number">97</span> <span class="token operator">&amp;&amp;</span> c <span class="token operator">&lt;=</span> <span class="token number">122</span><span class="token punctuation">)</span>
<span class="token keyword keyword-return">return</span> String<span class="token punctuation">.</span><span class="token function">fromCharCode</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>c <span class="token operator">-</span> <span class="token number">97</span> <span class="token operator">+</span> n<span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">26</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">97</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> l<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">caesarCipher</span><span class="token punctuation">(</span><span class="token string">&apos;Hello World!&apos;</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Ebiil Tloia!&apos;</span>
<span class="token function">caesarCipher</span><span class="token punctuation">(</span><span class="token string">&apos;Ebiil Tloia!&apos;</span><span class="token punctuation">,</span> <span class="token number">23</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Hello World!&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: call">title: call</h2>
<p>Given a key and a set of arguments, call them when given a context.</p>
<ul>
<li>Use a closure to call <code>key</code> with <code>args</code> for the given <code>context</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">call</span> <span class="token operator">=</span> <span class="token punctuation">(</span>key<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> context <span class="token operator">=&gt;</span> context<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript">Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token string">&apos;map&apos;</span><span class="token punctuation">,</span> x <span class="token operator">=&gt;</span> <span class="token number">2</span> <span class="token operator">*</span> x<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [ 2, 4, 6 ]</span>
<span class="token keyword keyword-const">const</span> map <span class="token operator">=</span> call<span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword keyword-null">null</span><span class="token punctuation">,</span> <span class="token string">&apos;map&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token function">map</span><span class="token punctuation">(</span>x <span class="token operator">=&gt;</span> <span class="token number">2</span> <span class="token operator">*</span> x<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [ 2, 4, 6 ]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: capitalize">title: capitalize</h2>
<p>Capitalizes the first letter of a string.</p>
<ul>
<li>Use array destructuring and <code>String.prototype.toUpperCase()</code> to capitalize the first letter of the string.</li>
<li>Use <code>Array.prototype.join(&apos;&apos;)</code> to combine the capitalized <code>first</code> with the <code>...rest</code> of the characters.</li>
<li>Omit the <code>lowerRest</code> argument to keep the rest of the string intact, or set it to <code>true</code> to convert to lowercase.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">capitalize</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">[</span>first<span class="token punctuation">,</span> <span class="token operator">...</span>rest<span class="token punctuation">]</span><span class="token punctuation">,</span> lowerRest <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
first<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span>
<span class="token punctuation">(</span>lowerRest <span class="token operator">?</span> rest<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> rest<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">capitalize</span><span class="token punctuation">(</span><span class="token string">&apos;fooBar&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;FooBar&apos;</span>
<span class="token function">capitalize</span><span class="token punctuation">(</span><span class="token string">&apos;fooBar&apos;</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Foobar&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: capitalizeEveryWord">title: capitalizeEveryWord</h2>
<p>Capitalizes the first letter of every word in a string.</p>
<ul>
<li>Use <code>String.prototype.replace()</code> to match the first character of each word and <code>String.prototype.toUpperCase()</code> to capitalize it.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">capitalizeEveryWord</span> <span class="token operator">=</span> str <span class="token operator">=&gt;</span>
str<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/\b[a-z]/g</span><span class="token punctuation">,</span> char <span class="token operator">=&gt;</span> char<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">capitalizeEveryWord</span><span class="token punctuation">(</span><span class="token string">&apos;hello world!&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Hello World!&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: cartesianProduct">title: cartesianProduct</h2>
<p>Calculates the cartesian product of two arrays.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code>, <code>Array.prototype.map()</code> and the spread operator (<code>...</code>) to generate all possible element pairs from the two arrays.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">cartesianProduct</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
a<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span> x<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">[</span><span class="token operator">...</span>p<span class="token punctuation">,</span> <span class="token operator">...</span>b<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>y <span class="token operator">=&gt;</span> <span class="token punctuation">[</span>x<span class="token punctuation">,</span> y<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">cartesianProduct</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">&apos;x&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;y&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [[&apos;x&apos;, 1], [&apos;x&apos;, 2], [&apos;y&apos;, 1], [&apos;y&apos;, 2]]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: castArray">title: castArray</h2>
<p>Casts the provided value as an array if it&apos;s not one.</p>
<ul>
<li>Use <code>Array.prototype.isArray()</code> to determine if <code>val</code> is an array and return it as-is or encapsulated in an array accordingly.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">castArray</span> <span class="token operator">=</span> val <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token operator">?</span> val <span class="token punctuation">:</span> <span class="token punctuation">[</span>val<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">castArray</span><span class="token punctuation">(</span><span class="token string">&apos;foo&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [&apos;foo&apos;]</span>
<span class="token function">castArray</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: celsiusToFahrenheit&lt;br&gt;
unlisted: true">title: celsiusToFahrenheit<br>
unlisted: true</h2>
<p>Converts Celsius to Fahrenheit.</p>
<ul>
<li>Follow the conversion formula <code>F = 1.8 * C + 32</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">celsiusToFahrenheit</span> <span class="token operator">=</span> degrees <span class="token operator">=&gt;</span> <span class="token number">1.8</span> <span class="token operator">*</span> degrees <span class="token operator">+</span> <span class="token number">32</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">celsiusToFahrenheit</span><span class="token punctuation">(</span><span class="token number">33</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 91.4</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: chainAsync">title: chainAsync</h2>
<p>Chains asynchronous functions.</p>
<ul>
<li>Loop through an array of functions containing asynchronous events, calling <code>next</code> when each asynchronous event has completed.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">chainAsync</span> <span class="token operator">=</span> fns <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> curr <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> last <span class="token operator">=</span> fns<span class="token punctuation">[</span>fns<span class="token punctuation">.</span>length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">next</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> fn <span class="token operator">=</span> fns<span class="token punctuation">[</span>curr<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
fn <span class="token operator">===</span> last <span class="token operator">?</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token function">fn</span><span class="token punctuation">(</span>next<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">chainAsync</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
next <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&apos;0 seconds&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">setTimeout</span><span class="token punctuation">(</span>next<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
next <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&apos;1 second&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">setTimeout</span><span class="token punctuation">(</span>next<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&apos;2 second&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: changeLightness">title: changeLightness</h2>
<p>Changes the lightness value of an <code>hsl()</code> color string.</p>
<ul>
<li>Use <code>String.prototype.match()</code> to get an array of 3 strings with the numeric values.</li>
<li>Use <code>Array.prototype.map()</code> in combination with <code>Number</code> to convert them into an array of numeric values.</li>
<li>Make sure the lightness is within the valid range (between <code>0</code> and <code>100</code>), using <code>Math.max()</code> and <code>Math.min()</code>.</li>
<li>Use a template literal to create a new <code>hsl()</code> string with the updated value.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">changeLightness</span> <span class="token operator">=</span> <span class="token punctuation">(</span>delta<span class="token punctuation">,</span> hslStr<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> <span class="token punctuation">[</span>hue<span class="token punctuation">,</span> saturation<span class="token punctuation">,</span> lightness<span class="token punctuation">]</span> <span class="token operator">=</span> hslStr<span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span><span class="token regex">/\d+/g</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>Number<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> newLightness <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>
<span class="token number">0</span><span class="token punctuation">,</span>
Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> lightness <span class="token operator">+</span> <span class="token function">parseFloat</span><span class="token punctuation">(</span>delta<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token template-string"><span class="token string">`hsl(</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>hue<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>saturation<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">%, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>newLightness<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">%)`</span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">changeLightness</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token string">&apos;hsl(330, 50%, 50%)&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;hsl(330, 50%, 60%)&apos;</span>
<span class="token function">changeLightness</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token string">&apos;hsl(330, 50%, 50%)&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;hsl(330, 50%, 40%)&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: checkProp">title: checkProp</h2>
<p>Creates a function that will invoke a predicate function for the specified property on a given object.</p>
<ul>
<li>Return a curried function, that will invoke <code>predicate</code> for the specified <code>prop</code> on <code>obj</code> and return a boolean.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">checkProp</span> <span class="token operator">=</span> <span class="token punctuation">(</span>predicate<span class="token punctuation">,</span> prop<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> obj <span class="token operator">=&gt;</span> <span class="token operator">!</span><span class="token operator">!</span><span class="token function">predicate</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> lengthIs4 <span class="token operator">=</span> <span class="token function">checkProp</span><span class="token punctuation">(</span>l <span class="token operator">=&gt;</span> l <span class="token operator">===</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token string">&apos;length&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">lengthIs4</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token function">lengthIs4</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">lengthIs4</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false (Set uses Size, not length)</span>
<span class="token keyword keyword-const">const</span> session <span class="token operator">=</span> <span class="token punctuation">{</span> user<span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> validUserSession <span class="token operator">=</span> <span class="token function">checkProp</span><span class="token punctuation">(</span>u <span class="token operator">=&gt;</span> u<span class="token punctuation">.</span>active <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>u<span class="token punctuation">.</span>disabled<span class="token punctuation">,</span> <span class="token string">&apos;user&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">validUserSession</span><span class="token punctuation">(</span>session<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
session<span class="token punctuation">.</span>user<span class="token punctuation">.</span>active <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token function">validUserSession</span><span class="token punctuation">(</span>session<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token keyword keyword-const">const</span> noLength <span class="token operator">=</span> <span class="token function">checkProp</span><span class="token punctuation">(</span>l <span class="token operator">=&gt;</span> l <span class="token operator">===</span> undefined<span class="token punctuation">,</span> <span class="token string">&apos;length&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">noLength</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token function">noLength</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">noLength</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: chunk">title: chunk</h2>
<p>Chunks an array into smaller arrays of a specified size.</p>
<ul>
<li>Use <code>Array.from()</code> to create a new array, that fits the number of chunks that will be produced.</li>
<li>Use <code>Array.prototype.slice()</code> to map each element of the new array to a chunk the length of <code>size</code>.</li>
<li>If the original array can&apos;t be split evenly, the final chunk will contain the remaining elements.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">chunk</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> size<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Array<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span><span class="token punctuation">{</span> length<span class="token punctuation">:</span> Math<span class="token punctuation">.</span><span class="token function">ceil</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span>length <span class="token operator">/</span> size<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>v<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>i <span class="token operator">*</span> size<span class="token punctuation">,</span> i <span class="token operator">*</span> size <span class="token operator">+</span> size<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">chunk</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[1, 2], [3, 4], [5]]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: chunkIntoN">title: chunkIntoN</h2>
<p>Chunks an array into <code>n</code> smaller arrays.</p>
<ul>
<li>Use <code>Math.ceil()</code> and <code>Array.prototype.length</code> to get the size of each chunk.</li>
<li>Use <code>Array.from()</code> to create a new array of size <code>n</code>.</li>
<li>Use <code>Array.prototype.slice()</code> to map each element of the new array to a chunk the length of <code>size</code>.</li>
<li>If the original array can&apos;t be split evenly, the final chunk will contain the remaining elements.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">chunkIntoN</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> n<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> size <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">ceil</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span>length <span class="token operator">/</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> Array<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span><span class="token punctuation">{</span> length<span class="token punctuation">:</span> n <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>v<span class="token punctuation">,</span> i<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>i <span class="token operator">*</span> size<span class="token punctuation">,</span> i <span class="token operator">*</span> size <span class="token operator">+</span> size<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">chunkIntoN</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [[1, 2], [3, 4], [5, 6], [7]]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: chunkify">title: chunkify</h2>
<p>Chunks an iterable into smaller arrays of a specified size.</p>
<ul>
<li>Use a <code>for...of</code> loop over the given iterable, using <code>Array.prototype.push()</code> to add each new value to the current <code>chunk</code>.</li>
<li>Use <code>Array.prototype.length</code> to check if the current <code>chunk</code> is of the desired <code>size</code> and <code>yield</code> the value if it is.</li>
<li>Finally, use <code>Array.prototype.length</code> to check the final <code>chunk</code> and <code>yield</code> it if it&apos;s non-empty.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">chunkify</span> <span class="token operator">=</span> <span class="token keyword keyword-function">function</span><span class="token operator">*</span> <span class="token punctuation">(</span>itr<span class="token punctuation">,</span> size<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> chunk <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword keyword-for">for</span> <span class="token punctuation">(</span><span class="token keyword keyword-const">const</span> v <span class="token keyword keyword-of">of</span> itr<span class="token punctuation">)</span> <span class="token punctuation">{</span>
chunk<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>chunk<span class="token punctuation">.</span>length <span class="token operator">===</span> size<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-yield">yield</span> chunk<span class="token punctuation">;</span>
chunk <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>chunk<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token keyword keyword-yield">yield</span> chunk<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> x <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">[</span><span class="token operator">...</span><span class="token function">chunkify</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// [[1, 2], [3, 4], [5]]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: clampNumber">title: clampNumber</h2>
<p>Clamps <code>num</code> within the inclusive range specified by the boundary values <code>a</code> and <code>b</code>.</p>
<ul>
<li>If <code>num</code> falls within the range, return <code>num</code>.</li>
<li>Otherwise, return the nearest number in the range.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">clampNumber</span> <span class="token operator">=</span> <span class="token punctuation">(</span>num<span class="token punctuation">,</span> a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>num<span class="token punctuation">,</span> Math<span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">clampNumber</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span>
<span class="token function">clampNumber</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -1</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: cloneRegExp">title: cloneRegExp</h2>
<p>Clones a regular expression.</p>
<ul>
<li>Use <code>new RegExp()</code>, <code>RegExp.prototype.source</code> and <code>RegExp.prototype.flags</code> to clone the given regular expression.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">cloneRegExp</span> <span class="token operator">=</span> regExp <span class="token operator">=&gt;</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">RegExp</span><span class="token punctuation">(</span>regExp<span class="token punctuation">.</span>source<span class="token punctuation">,</span> regExp<span class="token punctuation">.</span>flags<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> regExp <span class="token operator">=</span> <span class="token regex">/lorem ipsum/gi</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> regExp2 <span class="token operator">=</span> <span class="token function">cloneRegExp</span><span class="token punctuation">(</span>regExp<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// regExp !== regExp2</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: coalesce">title: coalesce</h2>
<p>Returns the first defined, non-null argument.</p>
<ul>
<li>Use <code>Array.prototype.find()</code> and <code>Array.prototype.includes()</code> to find the first value that is not equal to <code>undefined</code> or <code>null</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">coalesce</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> args<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>v <span class="token operator">=&gt;</span> <span class="token operator">!</span><span class="token punctuation">[</span>undefined<span class="token punctuation">,</span> <span class="token keyword keyword-null">null</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">coalesce</span><span class="token punctuation">(</span><span class="token keyword keyword-null">null</span><span class="token punctuation">,</span> undefined<span class="token punctuation">,</span> <span class="token string">&apos;&apos;</span><span class="token punctuation">,</span> <span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token string">&apos;Waldo&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: coalesceFactory">title: coalesceFactory</h2>
<p>Customizes a coalesce function that returns the first argument which is true based on the given validator.</p>
<ul>
<li>Use <code>Array.prototype.find()</code> to return the first argument that returns <code>true</code> from the provided argument validation function, <code>valid</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">coalesceFactory</span> <span class="token operator">=</span> valid <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> args<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>valid<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> customCoalesce <span class="token operator">=</span> <span class="token function">coalesceFactory</span><span class="token punctuation">(</span>
v <span class="token operator">=&gt;</span> <span class="token operator">!</span><span class="token punctuation">[</span><span class="token keyword keyword-null">null</span><span class="token punctuation">,</span> undefined<span class="token punctuation">,</span> <span class="token string">&apos;&apos;</span><span class="token punctuation">,</span> <span class="token number">NaN</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">customCoalesce</span><span class="token punctuation">(</span>undefined<span class="token punctuation">,</span> <span class="token keyword keyword-null">null</span><span class="token punctuation">,</span> <span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token string">&apos;&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;Waldo&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Waldo&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: collectInto">title: collectInto</h2>
<p>Changes a function that accepts an array into a variadic function.</p>
<ul>
<li>Given a function, return a closure that collects all inputs into an array-accepting function.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">collectInto</span> <span class="token operator">=</span> fn <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">fn</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> Pall <span class="token operator">=</span> <span class="token function">collectInto</span><span class="token punctuation">(</span>Promise<span class="token punctuation">.</span>all<span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>Promise<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-let">let</span> p1 <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-let">let</span> p2 <span class="token operator">=</span> Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-let">let</span> p3 <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span>resolve <span class="token operator">=&gt;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Pall</span><span class="token punctuation">(</span>p1<span class="token punctuation">,</span> p2<span class="token punctuation">,</span> p3<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 2, 3] (after about 2 seconds)</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: colorize">title: colorize</h2>
<p>Adds special characters to text to print in color in the console (combined with <code>console.log()</code>).</p>
<ul>
<li>Use template literals and special characters to add the appropriate color code to the string output.</li>
<li>For background colors, add a special character that resets the background color at the end of the string.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">colorize</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
black<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[30m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">,</span>
red<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[31m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">,</span>
green<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[32m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">,</span>
yellow<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[33m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">,</span>
blue<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[34m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">,</span>
magenta<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[35m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">,</span>
cyan<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[36m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">,</span>
white<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[37m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">,</span>
bgBlack<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[40m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">\x1b[0m`</span></span><span class="token punctuation">,</span>
bgRed<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[41m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">\x1b[0m`</span></span><span class="token punctuation">,</span>
bgGreen<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[42m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">\x1b[0m`</span></span><span class="token punctuation">,</span>
bgYellow<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[43m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">\x1b[0m`</span></span><span class="token punctuation">,</span>
bgBlue<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[44m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">\x1b[0m`</span></span><span class="token punctuation">,</span>
bgMagenta<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[45m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">\x1b[0m`</span></span><span class="token punctuation">,</span>
bgCyan<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[46m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">\x1b[0m`</span></span><span class="token punctuation">,</span>
bgWhite<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`\x1b[47m</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>args<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">\x1b[0m`</span></span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">colorize</span><span class="token punctuation">(</span><span class="token string">&apos;foo&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span>red<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;foo&apos; (red letters)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">colorize</span><span class="token punctuation">(</span><span class="token string">&apos;foo&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;bar&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span>bgBlue<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;foo bar&apos; (blue background)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">colorize</span><span class="token punctuation">(</span><span class="token function">colorize</span><span class="token punctuation">(</span><span class="token string">&apos;foo&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span>yellow<span class="token punctuation">,</span> <span class="token function">colorize</span><span class="token punctuation">(</span><span class="token string">&apos;foo&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span>green<span class="token punctuation">)</span><span class="token punctuation">.</span>bgWhite<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// &apos;foo bar&apos; (first word in yellow letters, second word in green letters, white background for both)</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: combine">title: combine</h2>
<p>Combines two arrays of objects, using the specified key to match objects.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code> with an object accumulator to combine all objects in both arrays based on the given <code>prop</code>.</li>
<li>Use <code>Object.values()</code> to convert the resulting object to an array and return it.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">combine</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> prop<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Object<span class="token punctuation">.</span><span class="token function">values</span><span class="token punctuation">(</span>
<span class="token punctuation">[</span><span class="token operator">...</span>a<span class="token punctuation">,</span> <span class="token operator">...</span>b<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> v<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>v<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">)</span>
acc<span class="token punctuation">[</span>v<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">=</span> acc<span class="token punctuation">[</span>v<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">]</span>
<span class="token operator">?</span> <span class="token punctuation">{</span> <span class="token operator">...</span>acc<span class="token punctuation">[</span>v<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token operator">...</span>v <span class="token punctuation">}</span>
<span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token operator">...</span>v <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> acc<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> x <span class="token operator">=</span> <span class="token punctuation">[</span>
<span class="token punctuation">{</span> id<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">&apos;John&apos;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span> id<span class="token punctuation">:</span> <span class="token number">2</span><span class="token punctuation">,</span> name<span class="token punctuation">:</span> <span class="token string">&apos;Maria&apos;</span> <span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> y <span class="token operator">=</span> <span class="token punctuation">[</span>
<span class="token punctuation">{</span> id<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">28</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span> id<span class="token punctuation">:</span> <span class="token number">3</span><span class="token punctuation">,</span> age<span class="token punctuation">:</span> <span class="token number">26</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span> age<span class="token punctuation">:</span> <span class="token number">3</span><span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token function">combine</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> <span class="token string">&apos;id&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [</span>
<span class="token comment">// { id: 1, name: &apos;John&apos;, age: 28 },</span>
<span class="token comment">// { id: 2, name: &apos;Maria&apos; },</span>
<span class="token comment">// { id: 3, age: 26 }</span>
<span class="token comment">// ]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: compact">title: compact</h2>
<p>Removes falsy values from an array.</p>
<ul>
<li>Use <code>Array.prototype.filter()</code> to filter out falsy values (<code>false</code>, <code>null</code>, <code>0</code>, <code>&quot;&quot;</code>, <code>undefined</code>, and <code>NaN</code>).</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">compact</span> <span class="token operator">=</span> arr <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>Boolean<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">compact</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">&apos;&apos;</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;e&apos;</span> <span class="token operator">*</span> <span class="token number">23</span><span class="token punctuation">,</span> <span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token string">&apos;s&apos;</span><span class="token punctuation">,</span> <span class="token number">34</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// [ 1, 2, 3, &apos;a&apos;, &apos;s&apos;, 34 ]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: compactObject">title: compactObject</h2>
<p>Deeply removes all falsy values from an object or array.</p>
<ul>
<li>Use recursion.</li>
<li>Initialize the iterable data, using <code>Array.isArray()</code>, <code>Array.prototype.filter()</code> and <code>Boolean</code> for arrays in order to avoid sparse arrays.</li>
<li>Use <code>Object.keys()</code> and <code>Array.prototype.reduce()</code> to iterate over each key with an appropriate initial value.</li>
<li>Use <code>Boolean</code> to determine the truthiness of each key&apos;s value and add it to the accumulator if it&apos;s truthy.</li>
<li>Use <code>typeof</code> to determine if a given value is an <code>object</code> and call the function again to deeply compact it.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">compactObject</span> <span class="token operator">=</span> val <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> data <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token operator">?</span> val<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>Boolean<span class="token punctuation">)</span> <span class="token punctuation">:</span> val<span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>
<span class="token punctuation">(</span>acc<span class="token punctuation">,</span> key<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> value <span class="token operator">=</span> data<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span><span class="token function">Boolean</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">)</span>
acc<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword keyword-typeof">typeof</span> value <span class="token operator">===</span> <span class="token string">&apos;object&apos;</span> <span class="token operator">?</span> <span class="token function">compactObject</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token punctuation">:</span> value<span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> acc<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token punctuation">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
a<span class="token punctuation">:</span> <span class="token keyword keyword-null">null</span><span class="token punctuation">,</span>
b<span class="token punctuation">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
c<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
d<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
e<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
f<span class="token punctuation">:</span> <span class="token string">&apos;&apos;</span><span class="token punctuation">,</span>
g<span class="token punctuation">:</span> <span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span>
h<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token keyword keyword-null">null</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token string">&apos;&apos;</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">&apos;a&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
i<span class="token punctuation">:</span> <span class="token punctuation">{</span> j<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> k<span class="token punctuation">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> l<span class="token punctuation">:</span> <span class="token string">&apos;a&apos;</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token function">compactObject</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// { c: true, e: 1, g: &apos;a&apos;, h: [ true, 1, &apos;a&apos; ], i: { l: &apos;a&apos; } }</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: compactWhitespace">title: compactWhitespace</h2>
<p>Compacts whitespaces in a string.</p>
<ul>
<li>Use <code>String.prototype.replace()</code> with a regular expression to replace all occurrences of 2 or more whitespace characters with a single space.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">compactWhitespace</span> <span class="token operator">=</span> str <span class="token operator">=&gt;</span> str<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/\s{2,}/g</span><span class="token punctuation">,</span> <span class="token string">&apos; &apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">compactWhitespace</span><span class="token punctuation">(</span><span class="token string">&apos;Lorem Ipsum&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Lorem Ipsum&apos;</span>
<span class="token function">compactWhitespace</span><span class="token punctuation">(</span><span class="token string">&apos;Lorem \n Ipsum&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Lorem Ipsum&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: complement">title: complement</h2>
<p>Returns a function that is the logical complement of the given function, <code>fn</code>.</p>
<ul>
<li>Use the logical not (<code>!</code>) operator on the result of calling <code>fn</code> with any supplied <code>args</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">complement</span> <span class="token operator">=</span> fn <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token operator">!</span><span class="token function">fn</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">isEven</span> <span class="token operator">=</span> num <span class="token operator">=&gt;</span> num <span class="token operator">%</span> <span class="token number">2</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> isOdd <span class="token operator">=</span> <span class="token function">complement</span><span class="token punctuation">(</span>isEven<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">isOdd</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token function">isOdd</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: compose">title: compose</h2>
<p>Performs right-to-left function composition.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code> to perform right-to-left function composition.</li>
<li>The last (rightmost) function can accept one or more arguments; the remaining functions must be unary.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">compose</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">...</span>fns<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
fns<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>f<span class="token punctuation">,</span> g<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token function">g</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">add5</span> <span class="token operator">=</span> x <span class="token operator">=&gt;</span> x <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">multiply</span> <span class="token operator">=</span> <span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> x <span class="token operator">*</span> y<span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> multiplyAndAdd5 <span class="token operator">=</span> <span class="token function">compose</span><span class="token punctuation">(</span>
add5<span class="token punctuation">,</span>
multiply
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">multiplyAndAdd5</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 15</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: composeRight">title: composeRight</h2>
<p>Performs left-to-right function composition.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code> to perform left-to-right function composition.</li>
<li>The first (leftmost) function can accept one or more arguments; the remaining functions must be unary.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">composeRight</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token operator">...</span>fns<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
fns<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>f<span class="token punctuation">,</span> g<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">g</span><span class="token punctuation">(</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">add</span> <span class="token operator">=</span> <span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> x <span class="token operator">+</span> y<span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">square</span> <span class="token operator">=</span> x <span class="token operator">=&gt;</span> x <span class="token operator">*</span> x<span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> addAndSquare <span class="token operator">=</span> <span class="token function">composeRight</span><span class="token punctuation">(</span>add<span class="token punctuation">,</span> square<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">addAndSquare</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 9</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: containsWhitespace">title: containsWhitespace</h2>
<p>Checks if the given string contains any whitespace characters.</p>
<ul>
<li>Use <code>RegExp.prototype.test()</code> with an appropriate regular expression to check if the given string contains any whitespace characters.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">containsWhitespace</span> <span class="token operator">=</span> str <span class="token operator">=&gt;</span> <span class="token regex">/\s/</span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">containsWhitespace</span><span class="token punctuation">(</span><span class="token string">&apos;lorem&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token function">containsWhitespace</span><span class="token punctuation">(</span><span class="token string">&apos;lorem ipsum&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: converge">title: converge</h2>
<p>Accepts a converging function and a list of branching functions and returns a function that applies each branching function to the arguments and the results of the branching functions are passed as arguments to the converging function.</p>
<ul>
<li>Use <code>Array.prototype.map()</code> and <code>Function.prototype.apply()</code> to apply each function to the given arguments.</li>
<li>Use the spread operator (<code>...</code>) to call <code>converger</code> with the results of all other functions.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">converge</span> <span class="token operator">=</span> <span class="token punctuation">(</span>converger<span class="token punctuation">,</span> fns<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token function">converger</span><span class="token punctuation">(</span><span class="token operator">...</span>fns<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>fn <span class="token operator">=&gt;</span> fn<span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword keyword-null">null</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> average <span class="token operator">=</span> <span class="token function">converge</span><span class="token punctuation">(</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> a <span class="token operator">/</span> b<span class="token punctuation">,</span> <span class="token punctuation">[</span>
arr <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> v<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> a <span class="token operator">+</span> v<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
arr <span class="token operator">=&gt;</span> arr<span class="token punctuation">.</span>length
<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">average</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: copySign">title: copySign</h2>
<p>Returns the absolute value of the first number, but the sign of the second.</p>
<ul>
<li>Use <code>Math.sign()</code> to check if the two numbers have the same sign.</li>
<li>Return <code>x</code> if they do, <code>-x</code> otherwise.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">copySign</span> <span class="token operator">=</span> <span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> Math<span class="token punctuation">.</span><span class="token function">sign</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">===</span> Math<span class="token punctuation">.</span><span class="token function">sign</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span> <span class="token operator">?</span> x <span class="token punctuation">:</span> <span class="token operator">-</span>x<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">copySign</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span>
<span class="token function">copySign</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -2</span>
<span class="token function">copySign</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span>
<span class="token function">copySign</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// -2</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: copyToClipboard">title: copyToClipboard</h2>
<p>Copies a string to the clipboard.<br>
Only works as a result of user action (i.e. inside a <code>click</code> event listener).</p>
<ul>
<li>Create a new <code>&lt;textarea&gt;</code> element, fill it with the supplied data and add it to the HTML document.</li>
<li>Use <code>Selection.getRangeAt()</code>to store the selected range (if any).</li>
<li>Use <code>Document.execCommand(&apos;copy&apos;)</code> to copy to the clipboard.</li>
<li>Remove the <code>&lt;textarea&gt;</code> element from the HTML document.</li>
<li>Finally, use <code>Selection().addRange()</code> to recover the original selected range (if any).</li>
<li><strong>Note:</strong> You can use the new asynchronous Clipboard API to implement the same functionality. It&apos;s experimental but should be used in the future instead of this snippet. Find out more about it <a href="https://github.com/w3c/clipboard-apis/blob/master/explainer.adoc#writing-to-the-clipboard">here</a>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">copyToClipboard</span> <span class="token operator">=</span> str <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> el <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">&apos;textarea&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
el<span class="token punctuation">.</span>value <span class="token operator">=</span> str<span class="token punctuation">;</span>
el<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">&apos;readonly&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
el<span class="token punctuation">.</span>style<span class="token punctuation">.</span>position <span class="token operator">=</span> <span class="token string">&apos;absolute&apos;</span><span class="token punctuation">;</span>
el<span class="token punctuation">.</span>style<span class="token punctuation">.</span>left <span class="token operator">=</span> <span class="token string">&apos;-9999px&apos;</span><span class="token punctuation">;</span>
document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>el<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> selected <span class="token operator">=</span>
document<span class="token punctuation">.</span><span class="token function">getSelection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>rangeCount <span class="token operator">&gt;</span> <span class="token number">0</span>
<span class="token operator">?</span> document<span class="token punctuation">.</span><span class="token function">getSelection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getRangeAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
<span class="token punctuation">:</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
el<span class="token punctuation">.</span><span class="token function">select</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
document<span class="token punctuation">.</span><span class="token function">execCommand</span><span class="token punctuation">(</span><span class="token string">&apos;copy&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>el<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>selected<span class="token punctuation">)</span> <span class="token punctuation">{</span>
document<span class="token punctuation">.</span><span class="token function">getSelection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">removeAllRanges</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
document<span class="token punctuation">.</span><span class="token function">getSelection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addRange</span><span class="token punctuation">(</span>selected<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">copyToClipboard</span><span class="token punctuation">(</span><span class="token string">&apos;Lorem ipsum&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Lorem ipsum&apos; copied to clipboard.</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: countBy">title: countBy</h2>
<p>Groups the elements of an array based on the given function and returns the count of elements in each group.</p>
<ul>
<li>Use <code>Array.prototype.map()</code> to map the values of an array to a function or property name.</li>
<li>Use <code>Array.prototype.reduce()</code> to create an object, where the keys are produced from the mapped results.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">countBy</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword keyword-typeof">typeof</span> fn <span class="token operator">===</span> <span class="token string">&apos;function&apos;</span> <span class="token operator">?</span> fn <span class="token punctuation">:</span> val <span class="token operator">=&gt;</span> val<span class="token punctuation">[</span>fn<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> val<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
acc<span class="token punctuation">[</span>val<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span>acc<span class="token punctuation">[</span>val<span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> acc<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">countBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">6.1</span><span class="token punctuation">,</span> <span class="token number">4.2</span><span class="token punctuation">,</span> <span class="token number">6.3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span>floor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {4: 1, 6: 2}</span>
<span class="token function">countBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">&apos;one&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;two&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;three&apos;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">&apos;length&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {3: 2, 5: 1}</span>
<span class="token function">countBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">{</span> count<span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> count<span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> count<span class="token punctuation">:</span> <span class="token number">5</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span> x <span class="token operator">=&gt;</span> x<span class="token punctuation">.</span>count<span class="token punctuation">)</span>
<span class="token comment">// {5: 2, 10: 1}</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: countOccurrences">title: countOccurrences</h2>
<p>Counts the occurrences of a value in an array.</p>
<ul>
<li>Use <code>Array.prototype.reduce()</code> to increment a counter each time the specific value is encountered inside the array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">countOccurrences</span> <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> val<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> v<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>v <span class="token operator">===</span> val <span class="token operator">?</span> a <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">:</span> a<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">countOccurrences</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: countSubstrings">title: countSubstrings</h2>
<p>Counts the occurrences of a substring in a given string.</p>
<ul>
<li>Use <code>Array.prototype.indexOf()</code> to look for <code>searchValue</code> in <code>str</code>.</li>
<li>Increment a counter if the value is found and update the index, <code>i</code>.</li>
<li>Use a <code>while</code> loop that will return as soon as the value returned from <code>Array.prototype.indexOf()</code> is <code>-1</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">countSubstrings</span> <span class="token operator">=</span> <span class="token punctuation">(</span>str<span class="token punctuation">,</span> searchValue<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span>
i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-while">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> r <span class="token operator">=</span> str<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>searchValue<span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>r <span class="token operator">!==</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> i<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span>count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> r <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword keyword-else">else</span> <span class="token keyword keyword-return">return</span> count<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">countSubstrings</span><span class="token punctuation">(</span><span class="token string">&apos;tiktok tok tok tik tok tik&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;tik&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 3</span>
<span class="token function">countSubstrings</span><span class="token punctuation">(</span><span class="token string">&apos;tutut tut tut&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;tut&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: countWeekDaysBetween">title: countWeekDaysBetween</h2>
<p>Counts the weekdays between two dates.</p>
<ul>
<li>Use <code>Array.from()</code> to construct an array with <code>length</code> equal to the number of days between <code>startDate</code> and <code>endDate</code>.</li>
<li>Use <code>Array.prototype.reduce()</code> to iterate over the array, checking if each date is a weekday and incrementing <code>count</code>.</li>
<li>Update <code>startDate</code> with the next day each loop using <code>Date.prototype.getDate()</code> and <code>Date.prototype.setDate()</code> to advance it by one day.</li>
<li><strong>NOTE:</strong> Does not take official holidays into account.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">countWeekDaysBetween</span> <span class="token operator">=</span> <span class="token punctuation">(</span>startDate<span class="token punctuation">,</span> endDate<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Array
<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span><span class="token punctuation">{</span> length<span class="token punctuation">:</span> <span class="token punctuation">(</span>endDate <span class="token operator">-</span> startDate<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token punctuation">(</span><span class="token number">1000</span> <span class="token operator">*</span> <span class="token number">3600</span> <span class="token operator">*</span> <span class="token number">24</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>count <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>startDate<span class="token punctuation">.</span><span class="token function">getDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">6</span> <span class="token operator">!==</span> <span class="token number">0</span><span class="token punctuation">)</span> count<span class="token operator">++</span><span class="token punctuation">;</span>
startDate <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>startDate<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>startDate<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> count<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">countWeekDaysBetween</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">&apos;Oct 05, 2020&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">&apos;Oct 06, 2020&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1</span>
<span class="token function">countWeekDaysBetween</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">&apos;Oct 05, 2020&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">&apos;Oct 14, 2020&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 7</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: counter">title: counter</h2>
<p>Creates a counter with the specified range, step and duration for the specified selector.</p>
<ul>
<li>Check if <code>step</code> has the proper sign and change it accordingly.</li>
<li>Use <code>setInterval()</code> in combination with <code>Math.abs()</code> and <code>Math.floor()</code> to calculate the time between each new text draw.</li>
<li>Use <code>Document.querySelector()</code>, <code>Element.innerHTML</code> to update the value of the selected element.</li>
<li>Omit the fourth argument, <code>step</code>, to use a default step of <code>1</code>.</li>
<li>Omit the fifth argument, <code>duration</code>, to use a default duration of <code>2000</code>ms.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">counter</span> <span class="token operator">=</span> <span class="token punctuation">(</span>selector<span class="token punctuation">,</span> start<span class="token punctuation">,</span> end<span class="token punctuation">,</span> step <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span> duration <span class="token operator">=</span> <span class="token number">2000</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> current <span class="token operator">=</span> start<span class="token punctuation">,</span>
_step <span class="token operator">=</span> <span class="token punctuation">(</span>end <span class="token operator">-</span> start<span class="token punctuation">)</span> <span class="token operator">*</span> step <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token operator">-</span>step <span class="token punctuation">:</span> step<span class="token punctuation">,</span>
timer <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
current <span class="token operator">+=</span> _step<span class="token punctuation">;</span>
document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span>selector<span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> current<span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>current <span class="token operator">&gt;=</span> end<span class="token punctuation">)</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span>selector<span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> end<span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>current <span class="token operator">&gt;=</span> end<span class="token punctuation">)</span> <span class="token function">clearInterval</span><span class="token punctuation">(</span>timer<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span><span class="token function">abs</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>duration <span class="token operator">/</span> <span class="token punctuation">(</span>end <span class="token operator">-</span> start<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> timer<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">counter</span><span class="token punctuation">(</span><span class="token string">&apos;#my-id&apos;</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Creates a 2-second timer for the element with id=&quot;my-id&quot;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: createDirIfNotExists">title: createDirIfNotExists</h2>
<p>Creates a directory, if it does not exist.</p>
<ul>
<li>Use <code>fs.existsSync()</code> to check if the directory exists, <code>fs.mkdirSync()</code> to create it.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> fs <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&apos;fs&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> <span class="token function-variable function">createDirIfNotExists</span> <span class="token operator">=</span> dir <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token operator">!</span>fs<span class="token punctuation">.</span><span class="token function">existsSync</span><span class="token punctuation">(</span>dir<span class="token punctuation">)</span> <span class="token operator">?</span> fs<span class="token punctuation">.</span><span class="token function">mkdirSync</span><span class="token punctuation">(</span>dir<span class="token punctuation">)</span> <span class="token punctuation">:</span> undefined<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">createDirIfNotExists</span><span class="token punctuation">(</span><span class="token string">&apos;test&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// creates the directory &apos;test&apos;, if it doesn&apos;t exist</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: createElement">title: createElement</h2>
<p>Creates an element from a string (without appending it to the document).<br>
If the given string contains multiple elements, only the first one will be returned.</p>
<ul>
<li>Use <code>Document.createElement()</code> to create a new element.</li>
<li>Use <code>Element.innerHTML</code> to set its inner HTML to the string supplied as the argument.</li>
<li>Use <code>ParentNode.firstElementChild</code> to return the element version of the string.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">createElement</span> <span class="token operator">=</span> str <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> el <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">&apos;div&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
el<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> str<span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> el<span class="token punctuation">.</span>firstElementChild<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> el <span class="token operator">=</span> <span class="token function">createElement</span><span class="token punctuation">(</span>
<span class="token template-string"><span class="token string">`&lt;div class=&quot;container&quot;&gt;
&lt;p&gt;Hello!&lt;/p&gt;
&lt;/div&gt;`</span></span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>el<span class="token punctuation">.</span>className<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;container&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: createEventHub">title: createEventHub</h2>
<p>Creates a pub/sub (<a href="https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern">publish&#x2013;subscribe</a>) event hub with <code>emit</code>, <code>on</code>, and <code>off</code> methods.</p>
<ul>
<li>Use <code>Object.create(null)</code> to create an empty <code>hub</code> object that does not inherit properties from <code>Object.prototype</code>.</li>
<li>For <code>emit</code>, resolve the array of handlers based on the <code>event</code> argument and then run each one with <code>Array.prototype.forEach()</code> by passing in the data as an argument.</li>
<li>For <code>on</code>, create an array for the event if it does not yet exist, then use <code>Array.prototype.push()</code> to add the handler</li>
<li>to the array.</li>
<li>For <code>off</code>, use <code>Array.prototype.findIndex()</code> to find the index of the handler in the event array and remove it using <code>Array.prototype.splice()</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">createEventHub</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
hub<span class="token punctuation">:</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token keyword keyword-null">null</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token function">emit</span><span class="token punctuation">(</span>event<span class="token punctuation">,</span> data<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token punctuation">(</span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>hub<span class="token punctuation">[</span>event<span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>handler <span class="token operator">=&gt;</span> <span class="token function">handler</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token function">on</span><span class="token punctuation">(</span>event<span class="token punctuation">,</span> handler<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>hub<span class="token punctuation">[</span>event<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>hub<span class="token punctuation">[</span>event<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>hub<span class="token punctuation">[</span>event<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>handler<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token function">off</span><span class="token punctuation">(</span>event<span class="token punctuation">,</span> handler<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> i <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>hub<span class="token punctuation">[</span>event<span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">findIndex</span><span class="token punctuation">(</span>h <span class="token operator">=&gt;</span> h <span class="token operator">===</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>i <span class="token operator">&gt;</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>hub<span class="token punctuation">[</span>event<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">splice</span><span class="token punctuation">(</span>i<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span><span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>hub<span class="token punctuation">[</span>event<span class="token punctuation">]</span><span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword keyword-delete">delete</span> <span class="token keyword keyword-this">this</span><span class="token punctuation">.</span>hub<span class="token punctuation">[</span>event<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">handler</span> <span class="token operator">=</span> data <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> hub <span class="token operator">=</span> <span class="token function">createEventHub</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-let">let</span> increment <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token comment">// Subscribe: listen for different types of events</span>
hub<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">&apos;message&apos;</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span>
hub<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">&apos;message&apos;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&apos;Message event fired&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
hub<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">&apos;increment&apos;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> increment<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Publish: emit events to invoke all handlers subscribed to them, passing the data to them as an argument</span>
hub<span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">&apos;message&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;hello world&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// logs &apos;hello world&apos; and &apos;Message event fired&apos;</span>
hub<span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">&apos;message&apos;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> hello<span class="token punctuation">:</span> <span class="token string">&apos;world&apos;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// logs the object and &apos;Message event fired&apos;</span>
hub<span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">&apos;increment&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// `increment` variable is now 1</span>
<span class="token comment">// Unsubscribe: stop a specific handler from listening to the &apos;message&apos; event</span>
hub<span class="token punctuation">.</span><span class="token function">off</span><span class="token punctuation">(</span><span class="token string">&apos;message&apos;</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: currentURL">title: currentURL</h2>
<p>Returns the current URL.</p>
<ul>
<li>Use <code>Window.location.href</code> to get the current URL.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">currentURL</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> window<span class="token punctuation">.</span>location<span class="token punctuation">.</span>href<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">currentURL</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;https://www.google.com/&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: curry">title: curry</h2>
<p>Curries a function.</p>
<ul>
<li>Use recursion.</li>
<li>If the number of provided arguments (<code>args</code>) is sufficient, call the passed function <code>fn</code>.</li>
<li>Otherwise, use <code>Function.prototype.bind()</code> to return a curried function <code>fn</code> that expects the rest of the arguments.</li>
<li>If you want to curry a function that accepts a variable number of arguments (a variadic function, e.g. <code>Math.min()</code>), you can optionally pass the number of arguments to the second parameter <code>arity</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">curry</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> arity <span class="token operator">=</span> fn<span class="token punctuation">.</span>length<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arity <span class="token operator">&lt;=</span> args<span class="token punctuation">.</span>length <span class="token operator">?</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token punctuation">:</span> curry<span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword keyword-null">null</span><span class="token punctuation">,</span> fn<span class="token punctuation">,</span> arity<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">curry</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span>pow<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1024</span>
<span class="token function">curry</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span>min<span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: cycleGenerator">title: cycleGenerator</h2>
<p>Creates a generator, looping over the given array indefinitely.</p>
<ul>
<li>Use a non-terminating <code>while</code> loop, that will <code>yield</code> a value every time <code>Generator.prototype.next()</code> is called.</li>
<li>Use the module operator (<code>%</code>) with <code>Array.prototype.length</code> to get the next value&apos;s index and increment the counter after each <code>yield</code> statement.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">cycleGenerator</span> <span class="token operator">=</span> <span class="token keyword keyword-function">function</span><span class="token operator">*</span> <span class="token punctuation">(</span>arr<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword keyword-while">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-yield">yield</span> arr<span class="token punctuation">[</span>i <span class="token operator">%</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">]</span><span class="token punctuation">;</span>
i<span class="token operator">++</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> binaryCycle <span class="token operator">=</span> <span class="token function">cycleGenerator</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
binaryCycle<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: 0, done: false }</span>
binaryCycle<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: 1, done: false }</span>
binaryCycle<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: 0, done: false }</span>
binaryCycle<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { value: 1, done: false }</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: dateRangeGenerator">title: dateRangeGenerator</h2>
<p>Creates a generator, that generates all dates in the given range using the given step.</p>
<ul>
<li>Use a <code>while</code> loop to iterate from <code>start</code> to <code>end</code>, using <code>yield</code> to return each date in the range, using the <code>Date</code> constructor.</li>
<li>Use <code>Date.prototype.getDate()</code> and <code>Date.prototype.setDate()</code> to increment by <code>step</code> days after returning each subsequent value.</li>
<li>Omit the third argument, <code>step</code>, to use a default value of <code>1</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">dateRangeGenerator</span> <span class="token operator">=</span> <span class="token keyword keyword-function">function</span><span class="token operator">*</span> <span class="token punctuation">(</span>start<span class="token punctuation">,</span> end<span class="token punctuation">,</span> step <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> d <span class="token operator">=</span> start<span class="token punctuation">;</span>
<span class="token keyword keyword-while">while</span> <span class="token punctuation">(</span>d <span class="token operator">&lt;</span> end<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-yield">yield</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span>
d<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> step<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token punctuation">[</span><span class="token operator">...</span><span class="token function">dateRangeGenerator</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">&apos;2021-06-01&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">&apos;2021-06-04&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">// [ 2021-06-01, 2021-06-02, 2021-06-03 ]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: dayName">title: dayName</h2>
<p>Gets the name of the weekday from a <code>Date</code> object.</p>
<ul>
<li>Use <code>Date.prototype.toLocaleDateString()</code> with the <code>{ weekday: &apos;long&apos; }</code> option to retrieve the weekday.</li>
<li>Use the optional second argument to get a language-specific name or omit it to use the default locale.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">dayName</span> <span class="token operator">=</span> <span class="token punctuation">(</span>date<span class="token punctuation">,</span> locale<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
date<span class="token punctuation">.</span><span class="token function">toLocaleDateString</span><span class="token punctuation">(</span>locale<span class="token punctuation">,</span> <span class="token punctuation">{</span> weekday<span class="token punctuation">:</span> <span class="token string">&apos;long&apos;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">dayName</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Saturday&apos;</span>
<span class="token function">dayName</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token string">&apos;09/23/2020&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">&apos;de-DE&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Samstag&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: dayOfYear">title: dayOfYear</h2>
<p>Gets the day of the year (number in the range 1-366) from a <code>Date</code> object.</p>
<ul>
<li>Use <code>new Date()</code> and <code>Date.prototype.getFullYear()</code> to get the first day of the year as a <code>Date</code> object.</li>
<li>Subtract the first day of the year from <code>date</code> and divide with the milliseconds in each day to get the result.</li>
<li>Use <code>Math.floor()</code> to appropriately round the resulting day count to an integer.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">dayOfYear</span> <span class="token operator">=</span> date <span class="token operator">=&gt;</span>
Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span><span class="token punctuation">(</span>date <span class="token operator">-</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>date<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">1000</span> <span class="token operator">/</span> <span class="token number">60</span> <span class="token operator">/</span> <span class="token number">60</span> <span class="token operator">/</span> <span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">dayOfYear</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 272</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: daysAgo">title: daysAgo</h2>
<p>Calculates the date of <code>n</code> days ago from today as a string representation.</p>
<ul>
<li>Use <code>new Date()</code> to get the current date, <code>Math.abs()</code> and <code>Date.prototype.getDate()</code> to update the date accordingly and set to the result using <code>Date.prototype.setDate()</code>.</li>
<li>Use <code>Date.prototype.toISOString()</code> to return a string in <code>yyyy-mm-dd</code> format.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">daysAgo</span> <span class="token operator">=</span> n <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> d <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
d<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> Math<span class="token punctuation">.</span><span class="token function">abs</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> d<span class="token punctuation">.</span><span class="token function">toISOString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&apos;T&apos;</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">daysAgo</span><span class="token punctuation">(</span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2020-09-16 (if current date is 2020-10-06)</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: daysFromNow">title: daysFromNow</h2>
<p>Calculates the date of <code>n</code> days from today as a string representation.</p>
<ul>
<li>Use <code>new Date()</code> to get the current date, <code>Math.abs()</code> and <code>Date.prototype.getDate()</code> to update the date accordingly and set to the result using <code>Date.prototype.setDate()</code>.</li>
<li>Use <code>Date.prototype.toISOString()</code> to return a string in <code>yyyy-mm-dd</code> format.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">daysFromNow</span> <span class="token operator">=</span> n <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> d <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
d<span class="token punctuation">.</span><span class="token function">setDate</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> Math<span class="token punctuation">.</span><span class="token function">abs</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> d<span class="token punctuation">.</span><span class="token function">toISOString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">&apos;T&apos;</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">daysFromNow</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2020-10-13 (if current date is 2020-10-08)</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: daysInMonth">title: daysInMonth</h2>
<p>Gets the number of days in the given <code>month</code> of the specified <code>year</code>.</p>
<ul>
<li>Use the <code>new Date()</code> constructor to create a date from the given <code>year</code> and <code>month</code>.</li>
<li>Set the days parameter to <code>0</code> to get the last day of the previous month, as months are zero-indexed.</li>
<li>Use <code>Date.prototype.getDate()</code> to return the number of days in the given <code>month</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">daysInMonth</span> <span class="token operator">=</span> <span class="token punctuation">(</span>year<span class="token punctuation">,</span> month<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>year<span class="token punctuation">,</span> month<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">daysInMonth</span><span class="token punctuation">(</span><span class="token number">2020</span><span class="token punctuation">,</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 31</span>
<span class="token function">daysInMonth</span><span class="token punctuation">(</span><span class="token number">2024</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 29</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: debounce">title: debounce</h2>
<p>Creates a debounced function that delays invoking the provided function until at least <code>ms</code> milliseconds have elapsed since its last invocation.</p>
<ul>
<li>Each time the debounced function is invoked, clear the current pending timeout with <code>clearTimeout()</code>. Use <code>setTimeout()</code> to create a new timeout that delays invoking the function until at least <code>ms</code> milliseconds have elapsed.</li>
<li>Use <code>Function.prototype.apply()</code> to apply the <code>this</code> context to the function and provide the necessary arguments.</li>
<li>Omit the second argument, <code>ms</code>, to set the timeout at a default of <code>0</code> ms.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">debounce</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> ms <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> timeoutId<span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token keyword keyword-function">function</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">clearTimeout</span><span class="token punctuation">(</span>timeoutId<span class="token punctuation">)</span><span class="token punctuation">;</span>
timeoutId <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> fn<span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword keyword-this">this</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">,</span> ms<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript">window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>
<span class="token string">&apos;resize&apos;</span><span class="token punctuation">,</span>
<span class="token function">debounce</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">.</span>innerWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">.</span>innerHeight<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">250</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Will log the window dimensions at most every 250ms</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: debouncePromise">title: debouncePromise</h2>
<p>Creates a debounced function that returns a promise, but delays invoking the provided function until at least <code>ms</code> milliseconds have elapsed since the last time it was invoked.<br>
All promises returned during this time will return the same data.</p>
<ul>
<li>Each time the debounced function is invoked, clear the current pending timeout with <code>clearTimeout()</code> and use <code>setTimeout()</code> to create a new timeout that delays invoking the function until at least <code>ms</code> milliseconds has elapsed.</li>
<li>Use <code>Function.prototype.apply()</code> to apply the <code>this</code> context to the function and provide the necessary arguments.</li>
<li>Create a new <code>Promise</code> and add its <code>resolve</code> and <code>reject</code> callbacks to the <code>pending</code> promises stack.</li>
<li>When <code>setTimeout</code> is called, copy the current stack (as it can change between the provided function call and its resolution), clear it and call the provided function.</li>
<li>When the provided function resolves/rejects, resolve/reject all promises in the stack (copied when the function was called) with the returned data.</li>
<li>Omit the second argument, <code>ms</code>, to set the timeout at a default of <code>0</code> ms.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">debouncePromise</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> ms <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-let">let</span> timeoutId<span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> pending <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token keyword keyword-new">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span>res<span class="token punctuation">,</span> rej<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token function">clearTimeout</span><span class="token punctuation">(</span>timeoutId<span class="token punctuation">)</span><span class="token punctuation">;</span>
timeoutId <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> currentPending <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>pending<span class="token punctuation">]</span><span class="token punctuation">;</span>
pending<span class="token punctuation">.</span>length <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
Promise<span class="token punctuation">.</span><span class="token function">resolve</span><span class="token punctuation">(</span>fn<span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword keyword-this">this</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>
data <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
currentPending<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">{</span> resolve <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">resolve</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
error <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
currentPending<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">{</span> reject <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">reject</span><span class="token punctuation">(</span>error<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> ms<span class="token punctuation">)</span><span class="token punctuation">;</span>
pending<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span> resolve<span class="token punctuation">:</span> res<span class="token punctuation">,</span> reject<span class="token punctuation">:</span> rej <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">fn</span> <span class="token operator">=</span> arg <span class="token operator">=&gt;</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span>resolve <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token function">setTimeout</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;resolved&apos;</span><span class="token punctuation">,</span> arg<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> debounced <span class="token operator">=</span> <span class="token function">debouncePromise</span><span class="token punctuation">(</span>fn<span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">debounced</span><span class="token punctuation">(</span><span class="token string">&apos;foo&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">debounced</span><span class="token punctuation">(</span><span class="token string">&apos;bar&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Will log [&apos;resolved&apos;, &apos;bar&apos;] both times</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: decapitalize">title: decapitalize</h2>
<p>Decapitalizes the first letter of a string.</p>
<ul>
<li>Use array destructuring and <code>String.prototype.toLowerCase()</code> to decapitalize first letter, <code>...rest</code> to get array of characters after first letter and then <code>Array.prototype.join(&apos;&apos;)</code> to make it a string again.</li>
<li>Omit the <code>upperRest</code> argument to keep the rest of the string intact, or set it to <code>true</code> to convert to uppercase.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">decapitalize</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">[</span>first<span class="token punctuation">,</span> <span class="token operator">...</span>rest<span class="token punctuation">]</span><span class="token punctuation">,</span> upperRest <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
first<span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span>
<span class="token punctuation">(</span>upperRest <span class="token operator">?</span> rest<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> rest<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">&apos;&apos;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">decapitalize</span><span class="token punctuation">(</span><span class="token string">&apos;FooBar&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;fooBar&apos;</span>
<span class="token function">decapitalize</span><span class="token punctuation">(</span><span class="token string">&apos;FooBar&apos;</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;fOOBAR&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: deepClone">title: deepClone</h2>
<p>Creates a deep clone of an object.<br>
Clones primitives, arrays and objects, excluding class instances.</p>
<ul>
<li>Use recursion.</li>
<li>Check if the passed object is <code>null</code> and, if so, return <code>null</code>.</li>
<li>Use <code>Object.assign()</code> and an empty object (<code>{}</code>) to create a shallow clone of the original.</li>
<li>Use <code>Object.keys()</code> and <code>Array.prototype.forEach()</code> to determine which key-value pairs need to be deep cloned.</li>
<li>If the object is an <code>Array</code>, set the <code>clone</code>&apos;s <code>length</code> to that of the original and use <code>Array.from(clone)</code> to create a clone.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">deepClone</span> <span class="token operator">=</span> obj <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>obj <span class="token operator">===</span> <span class="token keyword keyword-null">null</span><span class="token punctuation">)</span> <span class="token keyword keyword-return">return</span> <span class="token keyword keyword-null">null</span><span class="token punctuation">;</span>
<span class="token keyword keyword-let">let</span> clone <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>clone<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>
key <span class="token operator">=&gt;</span>
<span class="token punctuation">(</span>clone<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span>
<span class="token keyword keyword-typeof">typeof</span> obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token string">&apos;object&apos;</span> <span class="token operator">?</span> <span class="token function">deepClone</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> obj<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
clone<span class="token punctuation">.</span>length <span class="token operator">=</span> obj<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> Array<span class="token punctuation">.</span><span class="token keyword keyword-from">from</span><span class="token punctuation">(</span>clone<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword keyword-return">return</span> clone<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> a <span class="token operator">=</span> <span class="token punctuation">{</span> foo<span class="token punctuation">:</span> <span class="token string">&apos;bar&apos;</span><span class="token punctuation">,</span> obj<span class="token punctuation">:</span> <span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> b<span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> b <span class="token operator">=</span> <span class="token function">deepClone</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// a !== b, a.obj !== b.obj</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: deepFlatten">title: deepFlatten</h2>
<p>Deep flattens an array.</p>
<ul>
<li>Use recursion.</li>
<li>Use <code>Array.prototype.concat()</code> with an empty array (<code>[]</code>) and the spread operator (<code>...</code>) to flatten an array.</li>
<li>Recursively flatten each element that is an array.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">deepFlatten</span> <span class="token operator">=</span> arr <span class="token operator">=&gt;</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span><span class="token operator">...</span>arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>v <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">deepFlatten</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span> <span class="token punctuation">:</span> v<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">deepFlatten</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 2, 3, 4, 5]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: deepFreeze">title: deepFreeze</h2>
<p>Deep freezes an object.</p>
<ul>
<li>Use <code>Object.keys()</code> to get all the properties of the passed object, <code>Array.prototype.forEach()</code> to iterate over them.</li>
<li>Call <code>Object.freeze(obj)</code> recursively on all properties, applying <code>deepFreeze()</code> as necessary.</li>
<li>Finally, use <code>Object.freeze()</code> to freeze the given object.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">deepFreeze</span> <span class="token operator">=</span> obj <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>prop <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span><span class="token keyword keyword-typeof">typeof</span> obj<span class="token punctuation">[</span>prop<span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token string">&apos;object&apos;</span><span class="token punctuation">)</span> <span class="token function">deepFreeze</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> Object<span class="token punctuation">.</span><span class="token function">freeze</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token string">&apos;use strict&apos;</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> val <span class="token operator">=</span> <span class="token function">deepFreeze</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
val<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token comment">// not allowed</span>
val<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> <span class="token comment">// not allowed as well</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: deepGet">title: deepGet</h2>
<p>Gets the target value in a nested JSON object, based on the <code>keys</code> array.</p>
<ul>
<li>Compare the keys you want in the nested JSON object as an <code>Array</code>.</li>
<li>Use <code>Array.prototype.reduce()</code> to get the values in the nested JSON object one by one.</li>
<li>If the key exists in the object, return the target value, otherwise return <code>null</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">deepGet</span> <span class="token operator">=</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> keys<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
keys<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>
<span class="token punctuation">(</span>xs<span class="token punctuation">,</span> x<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>xs <span class="token operator">&amp;&amp;</span> xs<span class="token punctuation">[</span>x<span class="token punctuation">]</span> <span class="token operator">!==</span> <span class="token keyword keyword-null">null</span> <span class="token operator">&amp;&amp;</span> xs<span class="token punctuation">[</span>x<span class="token punctuation">]</span> <span class="token operator">!==</span> undefined <span class="token operator">?</span> xs<span class="token punctuation">[</span>x<span class="token punctuation">]</span> <span class="token punctuation">:</span> <span class="token keyword keyword-null">null</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
obj
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-let">let</span> index <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> data <span class="token operator">=</span> <span class="token punctuation">{</span>
foo<span class="token punctuation">:</span> <span class="token punctuation">{</span>
foz<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
bar<span class="token punctuation">:</span> <span class="token punctuation">{</span>
baz<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">&apos;a&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;b&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;c&apos;</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token function">deepGet</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;foo&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;foz&apos;</span><span class="token punctuation">,</span> index<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// get 3</span>
<span class="token function">deepGet</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">&apos;foo&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;bar&apos;</span><span class="token punctuation">,</span> <span class="token string">&apos;baz&apos;</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token string">&apos;foz&apos;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// null</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: deepMapKeys">title: deepMapKeys</h2>
<p>Deep maps an object&apos;s keys.</p>
<ul>
<li>Creates an object with the same values as the provided object and keys generated by running the provided function for each key.</li>
<li>Use <code>Object.keys(obj)</code> to iterate over the object&apos;s keys.</li>
<li>Use <code>Array.prototype.reduce()</code> to create a new object with the same values and mapped keys using <code>fn</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">deepMapKeys</span> <span class="token operator">=</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span>
<span class="token operator">?</span> obj<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>val <span class="token operator">=&gt;</span> <span class="token function">deepMapKeys</span><span class="token punctuation">(</span>val<span class="token punctuation">,</span> fn<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">:</span> <span class="token keyword keyword-typeof">typeof</span> obj <span class="token operator">===</span> <span class="token string">&apos;object&apos;</span>
<span class="token operator">?</span> Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> current<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> key <span class="token operator">=</span> <span class="token function">fn</span><span class="token punctuation">(</span>current<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> val <span class="token operator">=</span> obj<span class="token punctuation">[</span>current<span class="token punctuation">]</span><span class="token punctuation">;</span>
acc<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span>
val <span class="token operator">!==</span> <span class="token keyword keyword-null">null</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword keyword-typeof">typeof</span> val <span class="token operator">===</span> <span class="token string">&apos;object&apos;</span> <span class="token operator">?</span> <span class="token function">deepMapKeys</span><span class="token punctuation">(</span>val<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token punctuation">:</span> val<span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> acc<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">:</span> obj<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
foo<span class="token punctuation">:</span> <span class="token string">&apos;1&apos;</span><span class="token punctuation">,</span>
nested<span class="token punctuation">:</span> <span class="token punctuation">{</span>
child<span class="token punctuation">:</span> <span class="token punctuation">{</span>
withArray<span class="token punctuation">:</span> <span class="token punctuation">[</span>
<span class="token punctuation">{</span>
grandChild<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">&apos;hello&apos;</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword keyword-const">const</span> upperKeysObj <span class="token operator">=</span> <span class="token function">deepMapKeys</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> key <span class="token operator">=&gt;</span> key<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">/*
{
&quot;FOO&quot;:&quot;1&quot;,
&quot;NESTED&quot;:{
&quot;CHILD&quot;:{
&quot;WITHARRAY&quot;:[
{
&quot;GRANDCHILD&quot;:[ &apos;hello&apos; ]
}
]
}
}
}
*/</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: deepMerge">title: deepMerge</h2>
<p>Deeply merges two objects, using a function to handle keys present in both.</p>
<ul>
<li>Use <code>Object.keys()</code> to get the keys of both objects, create a <code>Set</code> from them and use the spread operator (<code>...</code>) to create an array of all the unique keys.</li>
<li>Use <code>Array.prototype.reduce()</code> to add each unique key to the object, using <code>fn</code> to combine the values of the two given objects.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">deepMerge</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token punctuation">[</span><span class="token operator">...</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">...</span>Object<span class="token punctuation">.</span><span class="token function">keys</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>
<span class="token punctuation">(</span>acc<span class="token punctuation">,</span> key<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token operator">...</span>acc<span class="token punctuation">,</span> <span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">:</span> <span class="token function">fn</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> a<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">,</span> b<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">deepMerge</span><span class="token punctuation">(</span>
<span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> b<span class="token punctuation">:</span> <span class="token punctuation">{</span> c<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> b<span class="token punctuation">:</span> <span class="token punctuation">{</span> d<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span>key<span class="token punctuation">,</span> a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>key <span class="token operator">===</span> <span class="token string">&apos;a&apos;</span> <span class="token operator">?</span> a <span class="token operator">&amp;&amp;</span> b <span class="token punctuation">:</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// { a: false, b: { c: [ 1, 2, 3 ], d: [ 1, 2, 3 ] } }</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: defaults">title: defaults</h2>
<p>Assigns default values for all properties in an object that are <code>undefined</code>.</p>
<ul>
<li>Use <code>Object.assign()</code> to create a new empty object and copy the original one to maintain key order.</li>
<li>Use <code>Array.prototype.reverse()</code> and the spread operator (<code>...</code>) to combine the default values from left to right.</li>
<li>Finally, use <code>obj</code> again to overwrite properties that originally had a value.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">defaults</span> <span class="token operator">=</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token operator">...</span>defs<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> obj<span class="token punctuation">,</span> <span class="token operator">...</span>defs<span class="token punctuation">.</span><span class="token function">reverse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">defaults</span><span class="token punctuation">(</span><span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> b<span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> b<span class="token punctuation">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> a<span class="token punctuation">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { a: 1, b: 2 }</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: defer">title: defer</h2>
<p>Defers invoking a function until the current call stack has cleared.</p>
<ul>
<li>Use <code>setTimeout()</code> with a timeout of <code>1</code> ms to add a new event to the event queue and allow the rendering engine to complete its work.</li>
<li>Use the spread (<code>...</code>) operator to supply the function with an arbitrary number of arguments.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">defer</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>fn<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token comment">// Example A:</span>
<span class="token function">defer</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>log<span class="token punctuation">,</span> <span class="token string">&apos;a&apos;</span><span class="token punctuation">)</span><span class="token punctuation">,</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&apos;b&apos;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// logs &apos;b&apos; then &apos;a&apos;</span>
<span class="token comment">// Example B:</span>
document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">&apos;#someElement&apos;</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">&apos;Hello&apos;</span><span class="token punctuation">;</span>
<span class="token function">longRunningFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Browser will not update the HTML until this has finished</span>
<span class="token function">defer</span><span class="token punctuation">(</span>longRunningFunction<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Browser will update the HTML then run the function</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: degreesToRads">title: degreesToRads</h2>
<p>Converts an angle from degrees to radians.</p>
<ul>
<li>Use <code>Math.PI</code> and the degree to radian formula to convert the angle from degrees to radians.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">degreesToRads</span> <span class="token operator">=</span> deg <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>deg <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token constant">PI</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">180.0</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">degreesToRads</span><span class="token punctuation">(</span><span class="token number">90.0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ~1.5708</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: delay">title: delay</h2>
<p>Invokes the provided function after <code>ms</code> milliseconds.</p>
<ul>
<li>Use <code>setTimeout()</code> to delay execution of <code>fn</code>.</li>
<li>Use the spread (<code>...</code>) operator to supply the function with an arbitrary number of arguments.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">delay</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> ms<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span>fn<span class="token punctuation">,</span> ms<span class="token punctuation">,</span> <span class="token operator">...</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">delay</span><span class="token punctuation">(</span>
<span class="token keyword keyword-function">function</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token number">1000</span><span class="token punctuation">,</span>
<span class="token string">&apos;later&apos;</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Logs &apos;later&apos; after one second.</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: detectDeviceType">title: detectDeviceType</h2>
<p>Detects whether the page is being viewed on a mobile device or a desktop.</p>
<ul>
<li>Use a regular expression to test the <code>navigator.userAgent</code> property to figure out if the device is a mobile device or a desktop.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">detectDeviceType</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
<span class="token regex">/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i</span><span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span>
navigator<span class="token punctuation">.</span>userAgent
<span class="token punctuation">)</span>
<span class="token operator">?</span> <span class="token string">&apos;Mobile&apos;</span>
<span class="token punctuation">:</span> <span class="token string">&apos;Desktop&apos;</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">detectDeviceType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;Mobile&apos; or &apos;Desktop&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: detectLanguage">title: detectLanguage</h2>
<p>Detects the preferred language of the current user.</p>
<ul>
<li>Use <code>NavigationLanguage.language</code> or the first <code>NavigationLanguage.languages</code> if available, otherwise return <code>defaultLang</code>.</li>
<li>Omit the second argument, <code>defaultLang</code>, to use <code>&apos;en-US&apos;</code> as the default language code.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> detectLanguage <span class="token operator">=</span> <span class="token punctuation">(</span>defaultLang <span class="token operator">=</span> <span class="token string">&apos;en-US&apos;</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
navigator<span class="token punctuation">.</span>language <span class="token operator">||</span>
<span class="token punctuation">(</span>Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>navigator<span class="token punctuation">.</span>languages<span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> navigator<span class="token punctuation">.</span>languages<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">||</span>
defaultLang<span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">detectLanguage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &apos;nl-NL&apos;</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: difference">title: difference</h2>
<p>Calculates the difference between two arrays, without filtering duplicate values.</p>
<ul>
<li>Create a <code>Set</code> from <code>b</code> to get the unique values in <code>b</code>.</li>
<li>Use <code>Array.prototype.filter()</code> on <code>a</code> to only keep values not contained in <code>b</code>, using <code>Set.prototype.has()</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">difference</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> s <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> a<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>x <span class="token operator">=&gt;</span> <span class="token operator">!</span>s<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">difference</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [3, 3]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: differenceBy">title: differenceBy</h2>
<p>Returns the difference between two arrays, after applying the provided function to each array element of both.</p>
<ul>
<li>Create a <code>Set</code> by applying <code>fn</code> to each element in <code>b</code>.</li>
<li>Use <code>Array.prototype.map()</code> to apply <code>fn</code> to each element in <code>a</code>.</li>
<li>Use <code>Array.prototype.filter()</code> in combination with <code>fn</code> on <code>a</code> to only keep values not contained in <code>b</code>, using <code>Set.prototype.has()</code>.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">differenceBy</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">,</span> fn<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-const">const</span> s <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>b<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword keyword-return">return</span> a<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>fn<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>el <span class="token operator">=&gt;</span> <span class="token operator">!</span>s<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>el<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">differenceBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">2.1</span><span class="token punctuation">,</span> <span class="token number">1.2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">2.3</span><span class="token punctuation">,</span> <span class="token number">3.4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> Math<span class="token punctuation">.</span>floor<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1]</span>
<span class="token function">differenceBy</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">{</span> x<span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> x<span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">{</span> x<span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span> v <span class="token operator">=&gt;</span> v<span class="token punctuation">.</span>x<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [2]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: differenceWith">title: differenceWith</h2>
<p>Filters out all values from an array for which the comparator function does not return <code>true</code>.</p>
<ul>
<li>Use <code>Array.prototype.filter()</code> and <code>Array.prototype.findIndex()</code> to find the appropriate values.</li>
<li>Omit the last argument, <code>comp</code>, to use a default strict equality comparator.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> differenceWith <span class="token operator">=</span> <span class="token punctuation">(</span>arr<span class="token punctuation">,</span> val<span class="token punctuation">,</span> <span class="token function-variable function">comp</span> <span class="token operator">=</span> <span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> a <span class="token operator">===</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>a <span class="token operator">=&gt;</span> val<span class="token punctuation">.</span><span class="token function">findIndex</span><span class="token punctuation">(</span>b <span class="token operator">=&gt;</span> <span class="token function">comp</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</pre><pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token function">differenceWith</span><span class="token punctuation">(</span>
<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">1.5</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token number">1.9</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> Math<span class="token punctuation">.</span><span class="token function">round</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span> <span class="token operator">===</span> Math<span class="token punctuation">.</span><span class="token function">round</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 1.2]</span>
<span class="token function">differenceWith</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1.2</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1.3</span><span class="token punctuation">,</span> <span class="token number">1.5</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1.2]</span>
</pre><hr>
<h2 ebook-toc-level-2 heading="title: dig">title: dig</h2>
<p>Gets the target value in a nested JSON object, based on the given key.</p>
<ul>
<li>Use the <code>in</code> operator to check if <code>target</code> exists in <code>obj</code>.</li>
<li>If found, return the value of <code>obj[target]</code>.</li>
<li>Otherwise use <code>Object.values(obj)</code> and <code>Array.prototype.reduce()</code> to recursively call <code>dig</code> on each nested object until the first matching key/value pair is found.</li>
</ul>
<pre data-role="codeBlock" data-info="js" class="language-javascript"><span class="token keyword keyword-const">const</span> <span class="token function-variable function">dig</span> <span class="token operator">=</span> <span class="token punctuation">(</span>obj<span class="token punctuation">,</span> target<span class
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment