Merge branch 'master' into browser-tests
This commit is contained in:
548
dist/_30s.es5.js
vendored
548
dist/_30s.es5.js
vendored
File diff suppressed because one or more lines are too long
2
dist/_30s.es5.min.js
vendored
2
dist/_30s.es5.min.js
vendored
File diff suppressed because one or more lines are too long
208
dist/_30s.esm.js
vendored
208
dist/_30s.esm.js
vendored
@ -39,6 +39,8 @@ const anagrams = str => {
|
||||
const arrayToHtmlList = (arr, listID) =>
|
||||
arr.map(item => (document.querySelector('#' + listID).innerHTML += `<li>${item}</li>`));
|
||||
|
||||
const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
|
||||
|
||||
const atob = str => new Buffer(str, 'base64').toString('binary');
|
||||
|
||||
const average = (...nums) => [...nums].reduce((acc, val) => acc + val, 0) / nums.length;
|
||||
@ -47,6 +49,16 @@ const averageBy = (arr, fn) =>
|
||||
arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => acc + val, 0) /
|
||||
arr.length;
|
||||
|
||||
const bind = (fn, context, ...args) =>
|
||||
function() {
|
||||
return fn.apply(context, args.concat(...arguments));
|
||||
};
|
||||
|
||||
const bindKey = (context, fn, ...args) =>
|
||||
function() {
|
||||
return context[fn].apply(context, args.concat(...arguments));
|
||||
};
|
||||
|
||||
const bottomVisible = () =>
|
||||
document.documentElement.clientHeight + window.scrollY >=
|
||||
(document.documentElement.scrollHeight || document.documentElement.clientHeight);
|
||||
@ -62,6 +74,8 @@ const capitalize = ([first, ...rest], lowerRest = false) =>
|
||||
|
||||
const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase());
|
||||
|
||||
const castArray = val => (Array.isArray(val) ? val : [val]);
|
||||
|
||||
const chainAsync = fns => {
|
||||
let curr = 0;
|
||||
const next = () => fns[curr++](next);
|
||||
@ -75,17 +89,6 @@ const chunk = (arr, size) =>
|
||||
|
||||
const clampNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b));
|
||||
|
||||
const cleanObj = (obj, keysToKeep = [], childIndicator) => {
|
||||
Object.keys(obj).forEach(key => {
|
||||
if (key === childIndicator) {
|
||||
cleanObj(obj[key], keysToKeep, childIndicator);
|
||||
} else if (!keysToKeep.includes(key)) {
|
||||
delete obj[key];
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
};
|
||||
|
||||
const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags);
|
||||
|
||||
const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_));
|
||||
@ -117,6 +120,8 @@ const compact = arr => arr.filter(Boolean);
|
||||
|
||||
const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));
|
||||
|
||||
const composeRight = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
|
||||
|
||||
const copyToClipboard = str => {
|
||||
const el = document.createElement('textarea');
|
||||
el.value = str;
|
||||
@ -172,10 +177,22 @@ const curry = (fn, arity = fn.length, ...args) =>
|
||||
const decapitalize = ([first, ...rest], upperRest = false) =>
|
||||
first.toLowerCase() + (upperRest ? rest.join('').toUpperCase() : rest.join(''));
|
||||
|
||||
const 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;
|
||||
};
|
||||
|
||||
const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));
|
||||
|
||||
const defaults = (obj, ...defs) => Object.assign({}, obj, ...defs.reverse(), obj);
|
||||
|
||||
const defer = (fn, ...args) => setTimeout(fn, 1, ...args);
|
||||
|
||||
const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
|
||||
|
||||
const detectDeviceType = () =>
|
||||
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
|
||||
? 'Mobile'
|
||||
@ -186,6 +203,11 @@ const difference = (a, b) => {
|
||||
return a.filter(x => !s.has(x));
|
||||
};
|
||||
|
||||
const differenceBy = (a, b, fn) => {
|
||||
const s = new Set(b.map(v => fn(v)));
|
||||
return a.filter(x => !s.has(fn(x)));
|
||||
};
|
||||
|
||||
const differenceWith = (arr, val, comp) => arr.filter(a => val.findIndex(b => comp(a, b)) === -1);
|
||||
|
||||
const digitize = n => [...`${n}`].map(i => parseInt(i));
|
||||
@ -278,7 +300,20 @@ const fibonacci = n =>
|
||||
|
||||
const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
|
||||
|
||||
const findLast = (arr, fn) => arr.filter(fn).slice(-1);
|
||||
const findKey = (obj, fn) => Object.keys(obj).find(key => fn(obj[key], key, obj));
|
||||
|
||||
const findLast = (arr, fn) => arr.filter(fn).slice(-1)[0];
|
||||
|
||||
const findLastIndex = (arr, fn) =>
|
||||
arr
|
||||
.map((val, i) => [i, val])
|
||||
.filter(val => fn(val[1], val[0], arr))
|
||||
.slice(-1)[0][0];
|
||||
|
||||
const findLastKey = (obj, fn) =>
|
||||
Object.keys(obj)
|
||||
.reverse()
|
||||
.find(key => fn(obj[key], key, obj));
|
||||
|
||||
const flatten = (arr, depth = 1) =>
|
||||
depth != 1
|
||||
@ -293,6 +328,13 @@ const forEachRight = (arr, callback) =>
|
||||
.reverse()
|
||||
.forEach(callback);
|
||||
|
||||
const forOwn = (obj, fn) => Object.keys(obj).forEach(key => fn(obj[key], key, obj));
|
||||
|
||||
const forOwnRight = (obj, fn) =>
|
||||
Object.keys(obj)
|
||||
.reverse()
|
||||
.forEach(key => fn(obj[key], key, obj));
|
||||
|
||||
const formatDuration = ms => {
|
||||
if (ms < 0) ms = -ms;
|
||||
const time = {
|
||||
@ -472,9 +514,18 @@ const intersection = (a, b) => {
|
||||
return a.filter(x => s.has(x));
|
||||
};
|
||||
|
||||
const invertKeyValues = obj =>
|
||||
const intersectionBy = (a, b, fn) => {
|
||||
const s = new Set(b.map(x => fn(x)));
|
||||
return a.filter(x => s.has(fn(x)));
|
||||
};
|
||||
|
||||
const intersectionWith = (a, b, comp) => a.filter(x => b.findIndex(y => comp(x, y)) !== -1);
|
||||
|
||||
const invertKeyValues = (obj, fn) =>
|
||||
Object.keys(obj).reduce((acc, key) => {
|
||||
acc[obj[key]] = key;
|
||||
const val = fn ? fn(obj[key]) : obj[key];
|
||||
acc[val] = acc[val] || [];
|
||||
acc[val].push(key);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
@ -494,6 +545,8 @@ const isBoolean = val => typeof val === 'boolean';
|
||||
|
||||
const isDivisible = (dividend, divisor) => dividend % divisor === 0;
|
||||
|
||||
const isEmpty = val => val == null || !(Object.keys(val) || val).length;
|
||||
|
||||
const isEven = num => num % 2 === 0;
|
||||
|
||||
const isFunction = val => typeof val === 'function';
|
||||
@ -508,6 +561,10 @@ const isNumber = val => typeof val === 'number';
|
||||
|
||||
const isObject = obj => obj === Object(obj);
|
||||
|
||||
const isObjectLike = val => val !== null && typeof val === 'object';
|
||||
|
||||
const isPlainObject = val => !!val && typeof val === 'object' && val.constructor === Object;
|
||||
|
||||
const isPrime = num => {
|
||||
const boundary = Math.floor(Math.sqrt(num));
|
||||
for (var i = 2; i <= boundary; i++) if (num % i == 0) return false;
|
||||
@ -602,6 +659,17 @@ const mapValues = (obj, fn) =>
|
||||
const mask = (cc, num = 4, mask = '*') =>
|
||||
('' + cc).slice(0, -num).replace(/./g, mask) + ('' + cc).slice(-num);
|
||||
|
||||
const matches = (obj, source) =>
|
||||
Object.keys(source).every(key => obj.hasOwnProperty(key) && obj[key] === source[key]);
|
||||
|
||||
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]
|
||||
);
|
||||
|
||||
const maxBy = (arr, fn) => Math.max(...arr.map(typeof fn === 'function' ? fn : val => val[fn]));
|
||||
|
||||
const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n);
|
||||
@ -637,6 +705,8 @@ const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n);
|
||||
|
||||
const negate = func => (...args) => !func(...args);
|
||||
|
||||
const nthArg = n => (...args) => args.slice(n)[0];
|
||||
|
||||
const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0];
|
||||
|
||||
const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {});
|
||||
@ -664,6 +734,16 @@ const observeMutations = (element, callback, options) => {
|
||||
|
||||
const off = (el, evt, fn, opts = false) => el.removeEventListener(evt, fn, opts);
|
||||
|
||||
const omit = (obj, arr) =>
|
||||
Object.keys(obj)
|
||||
.filter(k => !arr.includes(k))
|
||||
.reduce((acc, key) => (acc[key] = obj[key], acc), {});
|
||||
|
||||
const omitBy = (obj, fn) =>
|
||||
Object.keys(obj)
|
||||
.filter(k => !fn(obj[k], k))
|
||||
.reduce((acc, key) => (acc[key] = obj[key], acc), {});
|
||||
|
||||
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);
|
||||
@ -705,6 +785,8 @@ const orderBy = (arr, props, orders) =>
|
||||
}, 0)
|
||||
);
|
||||
|
||||
const over = (...fns) => (...args) => fns.map(fn => fn.apply(null, args));
|
||||
|
||||
const palindrome = str => {
|
||||
const s = str.toLowerCase().replace(/[\W_]/g, '');
|
||||
return (
|
||||
@ -725,6 +807,10 @@ const parseCookie = str =>
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const partial = (fn, ...partials) => (...args) => fn(...partials, ...args);
|
||||
|
||||
const partialRight = (fn, ...partials) => (...args) => fn(...args, ...partials);
|
||||
|
||||
const partition = (arr, fn) =>
|
||||
arr.reduce(
|
||||
(acc, val, i, arr) => {
|
||||
@ -740,6 +826,11 @@ const percentile = (arr, val) =>
|
||||
const pick = (obj, arr) =>
|
||||
arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});
|
||||
|
||||
const pickBy = (obj, fn) =>
|
||||
Object.keys(obj)
|
||||
.filter(k => fn(obj[k], k))
|
||||
.reduce((acc, key) => (acc[key] = obj[key], acc), {});
|
||||
|
||||
const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
|
||||
|
||||
const pluralize = (val, word, plural = word + 's') => {
|
||||
@ -820,6 +911,12 @@ const readFileLines = filename =>
|
||||
const redirect = (url, asLink = true) =>
|
||||
asLink ? (window.location.href = url) : window.location.replace(url);
|
||||
|
||||
const reduceSuccessive = (arr, fn, acc) =>
|
||||
arr.reduce((res, val, i, arr) => (res.push(fn(res.slice(-1)[0], val, i, arr)), res), [acc]);
|
||||
|
||||
const reduceWhich = (arr, comparator = (a, b) => a - b) =>
|
||||
arr.reduce((a, b) => (comparator(a, b) >= 0 ? b : a));
|
||||
|
||||
const reducedFilter = (data, keys, fn) =>
|
||||
data.filter(fn).map(el =>
|
||||
keys.reduce((acc, key) => {
|
||||
@ -923,6 +1020,15 @@ const sortedIndex = (arr, n) => {
|
||||
return index === -1 ? arr.length : index;
|
||||
};
|
||||
|
||||
const sortedLastIndex = (arr, n) => {
|
||||
const isDescending = arr[0] > arr[arr.length - 1];
|
||||
const index = arr
|
||||
.map((val, i) => [i, val])
|
||||
.filter(el => (isDescending ? n >= el[1] : n >= el[1]))
|
||||
.slice(-1)[0][0];
|
||||
return index === -1 ? arr.length : index;
|
||||
};
|
||||
|
||||
const splitLines = str => str.split(/\r?\n/);
|
||||
|
||||
const spreadOver = fn => argsArr => fn(...argsArr);
|
||||
@ -952,6 +1058,17 @@ const symmetricDifference = (a, b) => {
|
||||
return [...a.filter(x => !sB.has(x)), ...b.filter(x => !sA.has(x))];
|
||||
};
|
||||
|
||||
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)))];
|
||||
};
|
||||
|
||||
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)
|
||||
];
|
||||
|
||||
const tail = arr => (arr.length > 1 ? arr.slice(1) : arr);
|
||||
|
||||
const take = (arr, n = 1) => arr.slice(0, n);
|
||||
@ -965,6 +1082,11 @@ const timeTaken = callback => {
|
||||
return r;
|
||||
};
|
||||
|
||||
const times = (n, fn, context = undefined) => {
|
||||
let i = 0;
|
||||
while (fn.call(context, i) !== false && ++i < n) {}
|
||||
};
|
||||
|
||||
const toCamelCase = str => {
|
||||
let s =
|
||||
str &&
|
||||
@ -1007,7 +1129,13 @@ const toSnakeCase = str =>
|
||||
|
||||
const toggleClass = (el, className) => el.classList.toggle(className);
|
||||
|
||||
const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0];
|
||||
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')}`;
|
||||
};
|
||||
|
||||
const transform = (obj, fn, acc) => Object.keys(obj).reduce((a, k) => fn(a, obj[k], k, obj), acc);
|
||||
|
||||
@ -1016,6 +1144,8 @@ const truncateString = (str, num) =>
|
||||
|
||||
const truthCheckCollection = (collection, pre) => collection.every(obj => obj[pre]);
|
||||
|
||||
const unary = fn => val => fn(val);
|
||||
|
||||
const unescapeHTML = str =>
|
||||
str.replace(
|
||||
/&|<|>|'|"/g,
|
||||
@ -1029,18 +1159,53 @@ const unescapeHTML = str =>
|
||||
}[tag] || tag)
|
||||
);
|
||||
|
||||
const unfold = (fn, seed) => {
|
||||
let result = [],
|
||||
val = [null, seed];
|
||||
while ((val = fn(val[1]))) result.push(val[0]);
|
||||
return result;
|
||||
};
|
||||
|
||||
const union = (a, b) => Array.from(new Set([...a, ...b]));
|
||||
|
||||
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)))]));
|
||||
};
|
||||
|
||||
const unionWith = (a, b, comp) =>
|
||||
Array.from(new Set([...a, ...b.filter(x => a.findIndex(y => comp(x, y)) === -1)]));
|
||||
|
||||
const uniqueElements = arr => [...new Set(arr)];
|
||||
|
||||
const untildify = str => str.replace(/^~($|\/|\\)/, `${typeof require !== "undefined" && require('os').homedir()}$1`);
|
||||
|
||||
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 => [])
|
||||
);
|
||||
|
||||
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));
|
||||
|
||||
const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n;
|
||||
|
||||
const without = (arr, ...args) => arr.filter(v => !args.includes(v));
|
||||
|
||||
const words = (str, pattern = /[^a-zA-Z-]+/) => str.split(pattern).filter(Boolean);
|
||||
|
||||
const xProd = (a, b) => a.reduce((acc, x) => acc.concat(b.map(y => [x, y])), []);
|
||||
|
||||
const yesNo = (val, def = false) =>
|
||||
/^(y|yes)$/i.test(val) ? true : /^(n|no)$/i.test(val) ? false : def;
|
||||
|
||||
@ -1054,6 +1219,17 @@ const zip = (...arrays) => {
|
||||
const zipObject = (props, values) =>
|
||||
props.reduce((obj, prop, index) => (obj[prop] = values[index], obj), {});
|
||||
|
||||
var imports = {JSONToFile,RGBToHex,URLJoin,UUIDGeneratorBrowser,UUIDGeneratorNode,anagrams,arrayToHtmlList,atob,average,averageBy,bottomVisible,btoa,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,decapitalize,deepFlatten,defer,detectDeviceType,difference,differenceWith,digitize,distance,dropElements,dropRight,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findLast,flatten,flip,forEachRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,get,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,hashBrowser,hashNode,head,hexToRGB,hide,httpGet,httpPost,httpsRedirect,inRange,indexOfAll,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithRangeRight,initializeArrayWithValues,intersection,invertKeyValues,is,isAbsoluteURL,isArrayLike,isBoolean,isDivisible,isEven,isFunction,isLowerCase,isNil,isNull,isNumber,isObject,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isUndefined,isUpperCase,isValidJSON,join,last,lcm,longestItem,lowercaseKeys,luhnCheck,mapKeys,mapObject,mapValues,mask,maxBy,maxN,median,memoize,merge,minBy,minN,negate,nthElement,objectFromPairs,objectToPairs,observeMutations,off,on,onUserInputChange,once,orderBy,palindrome,parseCookie,partition,percentile,pick,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reducedFilter,remove,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,splitLines,spreadOver,standardDeviation,sum,sumBy,sumPower,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unescapeHTML,union,uniqueElements,untildify,validateNumber,without,words,yesNo,zip,zipObject,}
|
||||
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;
|
||||
};
|
||||
|
||||
var imports = {JSONToFile,RGBToHex,URLJoin,UUIDGeneratorBrowser,UUIDGeneratorNode,anagrams,arrayToHtmlList,ary,atob,average,averageBy,bind,bindKey,bottomVisible,btoa,byteSize,call,capitalize,capitalizeEveryWord,castArray,chainAsync,chunk,clampNumber,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,composeRight,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,decapitalize,deepClone,deepFlatten,defaults,defer,delay,detectDeviceType,difference,differenceBy,differenceWith,digitize,distance,dropElements,dropRight,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findKey,findLast,findLastIndex,findLastKey,flatten,flip,forEachRight,forOwn,forOwnRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,get,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,hashBrowser,hashNode,head,hexToRGB,hide,httpGet,httpPost,httpsRedirect,inRange,indexOfAll,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithRangeRight,initializeArrayWithValues,intersection,intersectionBy,intersectionWith,invertKeyValues,is,isAbsoluteURL,isArrayLike,isBoolean,isDivisible,isEmpty,isEven,isFunction,isLowerCase,isNil,isNull,isNumber,isObject,isObjectLike,isPlainObject,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isUndefined,isUpperCase,isValidJSON,join,last,lcm,longestItem,lowercaseKeys,luhnCheck,mapKeys,mapObject,mapValues,mask,matches,matchesWith,maxBy,maxN,median,memoize,merge,minBy,minN,negate,nthArg,nthElement,objectFromPairs,objectToPairs,observeMutations,off,omit,omitBy,on,onUserInputChange,once,orderBy,over,palindrome,parseCookie,partial,partialRight,partition,percentile,pick,pickBy,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reduceSuccessive,reduceWhich,reducedFilter,remove,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,sortedLastIndex,splitLines,spreadOver,standardDeviation,sum,sumBy,sumPower,symmetricDifference,symmetricDifferenceBy,symmetricDifferenceWith,tail,take,takeRight,timeTaken,times,toCamelCase,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unary,unescapeHTML,unfold,union,unionBy,unionWith,uniqueElements,untildify,unzip,unzipWith,validateNumber,without,words,xProd,yesNo,zip,zipObject,zipWith,}
|
||||
|
||||
export default imports;
|
||||
|
||||
208
dist/_30s.js
vendored
208
dist/_30s.js
vendored
@ -45,6 +45,8 @@ const anagrams = str => {
|
||||
const arrayToHtmlList = (arr, listID) =>
|
||||
arr.map(item => (document.querySelector('#' + listID).innerHTML += `<li>${item}</li>`));
|
||||
|
||||
const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
|
||||
|
||||
const atob = str => new Buffer(str, 'base64').toString('binary');
|
||||
|
||||
const average = (...nums) => [...nums].reduce((acc, val) => acc + val, 0) / nums.length;
|
||||
@ -53,6 +55,16 @@ const averageBy = (arr, fn) =>
|
||||
arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => acc + val, 0) /
|
||||
arr.length;
|
||||
|
||||
const bind = (fn, context, ...args) =>
|
||||
function() {
|
||||
return fn.apply(context, args.concat(...arguments));
|
||||
};
|
||||
|
||||
const bindKey = (context, fn, ...args) =>
|
||||
function() {
|
||||
return context[fn].apply(context, args.concat(...arguments));
|
||||
};
|
||||
|
||||
const bottomVisible = () =>
|
||||
document.documentElement.clientHeight + window.scrollY >=
|
||||
(document.documentElement.scrollHeight || document.documentElement.clientHeight);
|
||||
@ -68,6 +80,8 @@ const capitalize = ([first, ...rest], lowerRest = false) =>
|
||||
|
||||
const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase());
|
||||
|
||||
const castArray = val => (Array.isArray(val) ? val : [val]);
|
||||
|
||||
const chainAsync = fns => {
|
||||
let curr = 0;
|
||||
const next = () => fns[curr++](next);
|
||||
@ -81,17 +95,6 @@ const chunk = (arr, size) =>
|
||||
|
||||
const clampNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b));
|
||||
|
||||
const cleanObj = (obj, keysToKeep = [], childIndicator) => {
|
||||
Object.keys(obj).forEach(key => {
|
||||
if (key === childIndicator) {
|
||||
cleanObj(obj[key], keysToKeep, childIndicator);
|
||||
} else if (!keysToKeep.includes(key)) {
|
||||
delete obj[key];
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
};
|
||||
|
||||
const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags);
|
||||
|
||||
const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_));
|
||||
@ -123,6 +126,8 @@ const compact = arr => arr.filter(Boolean);
|
||||
|
||||
const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));
|
||||
|
||||
const composeRight = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
|
||||
|
||||
const copyToClipboard = str => {
|
||||
const el = document.createElement('textarea');
|
||||
el.value = str;
|
||||
@ -178,10 +183,22 @@ const curry = (fn, arity = fn.length, ...args) =>
|
||||
const decapitalize = ([first, ...rest], upperRest = false) =>
|
||||
first.toLowerCase() + (upperRest ? rest.join('').toUpperCase() : rest.join(''));
|
||||
|
||||
const 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;
|
||||
};
|
||||
|
||||
const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));
|
||||
|
||||
const defaults = (obj, ...defs) => Object.assign({}, obj, ...defs.reverse(), obj);
|
||||
|
||||
const defer = (fn, ...args) => setTimeout(fn, 1, ...args);
|
||||
|
||||
const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
|
||||
|
||||
const detectDeviceType = () =>
|
||||
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
|
||||
? 'Mobile'
|
||||
@ -192,6 +209,11 @@ const difference = (a, b) => {
|
||||
return a.filter(x => !s.has(x));
|
||||
};
|
||||
|
||||
const differenceBy = (a, b, fn) => {
|
||||
const s = new Set(b.map(v => fn(v)));
|
||||
return a.filter(x => !s.has(fn(x)));
|
||||
};
|
||||
|
||||
const differenceWith = (arr, val, comp) => arr.filter(a => val.findIndex(b => comp(a, b)) === -1);
|
||||
|
||||
const digitize = n => [...`${n}`].map(i => parseInt(i));
|
||||
@ -284,7 +306,20 @@ const fibonacci = n =>
|
||||
|
||||
const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
|
||||
|
||||
const findLast = (arr, fn) => arr.filter(fn).slice(-1);
|
||||
const findKey = (obj, fn) => Object.keys(obj).find(key => fn(obj[key], key, obj));
|
||||
|
||||
const findLast = (arr, fn) => arr.filter(fn).slice(-1)[0];
|
||||
|
||||
const findLastIndex = (arr, fn) =>
|
||||
arr
|
||||
.map((val, i) => [i, val])
|
||||
.filter(val => fn(val[1], val[0], arr))
|
||||
.slice(-1)[0][0];
|
||||
|
||||
const findLastKey = (obj, fn) =>
|
||||
Object.keys(obj)
|
||||
.reverse()
|
||||
.find(key => fn(obj[key], key, obj));
|
||||
|
||||
const flatten = (arr, depth = 1) =>
|
||||
depth != 1
|
||||
@ -299,6 +334,13 @@ const forEachRight = (arr, callback) =>
|
||||
.reverse()
|
||||
.forEach(callback);
|
||||
|
||||
const forOwn = (obj, fn) => Object.keys(obj).forEach(key => fn(obj[key], key, obj));
|
||||
|
||||
const forOwnRight = (obj, fn) =>
|
||||
Object.keys(obj)
|
||||
.reverse()
|
||||
.forEach(key => fn(obj[key], key, obj));
|
||||
|
||||
const formatDuration = ms => {
|
||||
if (ms < 0) ms = -ms;
|
||||
const time = {
|
||||
@ -478,9 +520,18 @@ const intersection = (a, b) => {
|
||||
return a.filter(x => s.has(x));
|
||||
};
|
||||
|
||||
const invertKeyValues = obj =>
|
||||
const intersectionBy = (a, b, fn) => {
|
||||
const s = new Set(b.map(x => fn(x)));
|
||||
return a.filter(x => s.has(fn(x)));
|
||||
};
|
||||
|
||||
const intersectionWith = (a, b, comp) => a.filter(x => b.findIndex(y => comp(x, y)) !== -1);
|
||||
|
||||
const invertKeyValues = (obj, fn) =>
|
||||
Object.keys(obj).reduce((acc, key) => {
|
||||
acc[obj[key]] = key;
|
||||
const val = fn ? fn(obj[key]) : obj[key];
|
||||
acc[val] = acc[val] || [];
|
||||
acc[val].push(key);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
@ -500,6 +551,8 @@ const isBoolean = val => typeof val === 'boolean';
|
||||
|
||||
const isDivisible = (dividend, divisor) => dividend % divisor === 0;
|
||||
|
||||
const isEmpty = val => val == null || !(Object.keys(val) || val).length;
|
||||
|
||||
const isEven = num => num % 2 === 0;
|
||||
|
||||
const isFunction = val => typeof val === 'function';
|
||||
@ -514,6 +567,10 @@ const isNumber = val => typeof val === 'number';
|
||||
|
||||
const isObject = obj => obj === Object(obj);
|
||||
|
||||
const isObjectLike = val => val !== null && typeof val === 'object';
|
||||
|
||||
const isPlainObject = val => !!val && typeof val === 'object' && val.constructor === Object;
|
||||
|
||||
const isPrime = num => {
|
||||
const boundary = Math.floor(Math.sqrt(num));
|
||||
for (var i = 2; i <= boundary; i++) if (num % i == 0) return false;
|
||||
@ -608,6 +665,17 @@ const mapValues = (obj, fn) =>
|
||||
const mask = (cc, num = 4, mask = '*') =>
|
||||
('' + cc).slice(0, -num).replace(/./g, mask) + ('' + cc).slice(-num);
|
||||
|
||||
const matches = (obj, source) =>
|
||||
Object.keys(source).every(key => obj.hasOwnProperty(key) && obj[key] === source[key]);
|
||||
|
||||
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]
|
||||
);
|
||||
|
||||
const maxBy = (arr, fn) => Math.max(...arr.map(typeof fn === 'function' ? fn : val => val[fn]));
|
||||
|
||||
const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n);
|
||||
@ -643,6 +711,8 @@ const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n);
|
||||
|
||||
const negate = func => (...args) => !func(...args);
|
||||
|
||||
const nthArg = n => (...args) => args.slice(n)[0];
|
||||
|
||||
const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n, n + 1) : arr.slice(n))[0];
|
||||
|
||||
const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {});
|
||||
@ -670,6 +740,16 @@ const observeMutations = (element, callback, options) => {
|
||||
|
||||
const off = (el, evt, fn, opts = false) => el.removeEventListener(evt, fn, opts);
|
||||
|
||||
const omit = (obj, arr) =>
|
||||
Object.keys(obj)
|
||||
.filter(k => !arr.includes(k))
|
||||
.reduce((acc, key) => (acc[key] = obj[key], acc), {});
|
||||
|
||||
const omitBy = (obj, fn) =>
|
||||
Object.keys(obj)
|
||||
.filter(k => !fn(obj[k], k))
|
||||
.reduce((acc, key) => (acc[key] = obj[key], acc), {});
|
||||
|
||||
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);
|
||||
@ -711,6 +791,8 @@ const orderBy = (arr, props, orders) =>
|
||||
}, 0)
|
||||
);
|
||||
|
||||
const over = (...fns) => (...args) => fns.map(fn => fn.apply(null, args));
|
||||
|
||||
const palindrome = str => {
|
||||
const s = str.toLowerCase().replace(/[\W_]/g, '');
|
||||
return (
|
||||
@ -731,6 +813,10 @@ const parseCookie = str =>
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const partial = (fn, ...partials) => (...args) => fn(...partials, ...args);
|
||||
|
||||
const partialRight = (fn, ...partials) => (...args) => fn(...args, ...partials);
|
||||
|
||||
const partition = (arr, fn) =>
|
||||
arr.reduce(
|
||||
(acc, val, i, arr) => {
|
||||
@ -746,6 +832,11 @@ const percentile = (arr, val) =>
|
||||
const pick = (obj, arr) =>
|
||||
arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});
|
||||
|
||||
const pickBy = (obj, fn) =>
|
||||
Object.keys(obj)
|
||||
.filter(k => fn(obj[k], k))
|
||||
.reduce((acc, key) => (acc[key] = obj[key], acc), {});
|
||||
|
||||
const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
|
||||
|
||||
const pluralize = (val, word, plural = word + 's') => {
|
||||
@ -826,6 +917,12 @@ const readFileLines = filename =>
|
||||
const redirect = (url, asLink = true) =>
|
||||
asLink ? (window.location.href = url) : window.location.replace(url);
|
||||
|
||||
const reduceSuccessive = (arr, fn, acc) =>
|
||||
arr.reduce((res, val, i, arr) => (res.push(fn(res.slice(-1)[0], val, i, arr)), res), [acc]);
|
||||
|
||||
const reduceWhich = (arr, comparator = (a, b) => a - b) =>
|
||||
arr.reduce((a, b) => (comparator(a, b) >= 0 ? b : a));
|
||||
|
||||
const reducedFilter = (data, keys, fn) =>
|
||||
data.filter(fn).map(el =>
|
||||
keys.reduce((acc, key) => {
|
||||
@ -929,6 +1026,15 @@ const sortedIndex = (arr, n) => {
|
||||
return index === -1 ? arr.length : index;
|
||||
};
|
||||
|
||||
const sortedLastIndex = (arr, n) => {
|
||||
const isDescending = arr[0] > arr[arr.length - 1];
|
||||
const index = arr
|
||||
.map((val, i) => [i, val])
|
||||
.filter(el => (isDescending ? n >= el[1] : n >= el[1]))
|
||||
.slice(-1)[0][0];
|
||||
return index === -1 ? arr.length : index;
|
||||
};
|
||||
|
||||
const splitLines = str => str.split(/\r?\n/);
|
||||
|
||||
const spreadOver = fn => argsArr => fn(...argsArr);
|
||||
@ -958,6 +1064,17 @@ const symmetricDifference = (a, b) => {
|
||||
return [...a.filter(x => !sB.has(x)), ...b.filter(x => !sA.has(x))];
|
||||
};
|
||||
|
||||
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)))];
|
||||
};
|
||||
|
||||
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)
|
||||
];
|
||||
|
||||
const tail = arr => (arr.length > 1 ? arr.slice(1) : arr);
|
||||
|
||||
const take = (arr, n = 1) => arr.slice(0, n);
|
||||
@ -971,6 +1088,11 @@ const timeTaken = callback => {
|
||||
return r;
|
||||
};
|
||||
|
||||
const times = (n, fn, context = undefined) => {
|
||||
let i = 0;
|
||||
while (fn.call(context, i) !== false && ++i < n) {}
|
||||
};
|
||||
|
||||
const toCamelCase = str => {
|
||||
let s =
|
||||
str &&
|
||||
@ -1013,7 +1135,13 @@ const toSnakeCase = str =>
|
||||
|
||||
const toggleClass = (el, className) => el.classList.toggle(className);
|
||||
|
||||
const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0];
|
||||
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')}`;
|
||||
};
|
||||
|
||||
const transform = (obj, fn, acc) => Object.keys(obj).reduce((a, k) => fn(a, obj[k], k, obj), acc);
|
||||
|
||||
@ -1022,6 +1150,8 @@ const truncateString = (str, num) =>
|
||||
|
||||
const truthCheckCollection = (collection, pre) => collection.every(obj => obj[pre]);
|
||||
|
||||
const unary = fn => val => fn(val);
|
||||
|
||||
const unescapeHTML = str =>
|
||||
str.replace(
|
||||
/&|<|>|'|"/g,
|
||||
@ -1035,18 +1165,53 @@ const unescapeHTML = str =>
|
||||
}[tag] || tag)
|
||||
);
|
||||
|
||||
const unfold = (fn, seed) => {
|
||||
let result = [],
|
||||
val = [null, seed];
|
||||
while ((val = fn(val[1]))) result.push(val[0]);
|
||||
return result;
|
||||
};
|
||||
|
||||
const union = (a, b) => Array.from(new Set([...a, ...b]));
|
||||
|
||||
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)))]));
|
||||
};
|
||||
|
||||
const unionWith = (a, b, comp) =>
|
||||
Array.from(new Set([...a, ...b.filter(x => a.findIndex(y => comp(x, y)) === -1)]));
|
||||
|
||||
const uniqueElements = arr => [...new Set(arr)];
|
||||
|
||||
const untildify = str => str.replace(/^~($|\/|\\)/, `${typeof require !== "undefined" && require('os').homedir()}$1`);
|
||||
|
||||
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 => [])
|
||||
);
|
||||
|
||||
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));
|
||||
|
||||
const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n;
|
||||
|
||||
const without = (arr, ...args) => arr.filter(v => !args.includes(v));
|
||||
|
||||
const words = (str, pattern = /[^a-zA-Z-]+/) => str.split(pattern).filter(Boolean);
|
||||
|
||||
const xProd = (a, b) => a.reduce((acc, x) => acc.concat(b.map(y => [x, y])), []);
|
||||
|
||||
const yesNo = (val, def = false) =>
|
||||
/^(y|yes)$/i.test(val) ? true : /^(n|no)$/i.test(val) ? false : def;
|
||||
|
||||
@ -1060,7 +1225,18 @@ const zip = (...arrays) => {
|
||||
const zipObject = (props, values) =>
|
||||
props.reduce((obj, prop, index) => (obj[prop] = values[index], obj), {});
|
||||
|
||||
var imports = {JSONToFile,RGBToHex,URLJoin,UUIDGeneratorBrowser,UUIDGeneratorNode,anagrams,arrayToHtmlList,atob,average,averageBy,bottomVisible,btoa,byteSize,call,capitalize,capitalizeEveryWord,chainAsync,chunk,clampNumber,cleanObj,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,decapitalize,deepFlatten,defer,detectDeviceType,difference,differenceWith,digitize,distance,dropElements,dropRight,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findLast,flatten,flip,forEachRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,get,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,hashBrowser,hashNode,head,hexToRGB,hide,httpGet,httpPost,httpsRedirect,inRange,indexOfAll,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithRangeRight,initializeArrayWithValues,intersection,invertKeyValues,is,isAbsoluteURL,isArrayLike,isBoolean,isDivisible,isEven,isFunction,isLowerCase,isNil,isNull,isNumber,isObject,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isUndefined,isUpperCase,isValidJSON,join,last,lcm,longestItem,lowercaseKeys,luhnCheck,mapKeys,mapObject,mapValues,mask,maxBy,maxN,median,memoize,merge,minBy,minN,negate,nthElement,objectFromPairs,objectToPairs,observeMutations,off,on,onUserInputChange,once,orderBy,palindrome,parseCookie,partition,percentile,pick,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reducedFilter,remove,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,splitLines,spreadOver,standardDeviation,sum,sumBy,sumPower,symmetricDifference,tail,take,takeRight,timeTaken,toCamelCase,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unescapeHTML,union,uniqueElements,untildify,validateNumber,without,words,yesNo,zip,zipObject,}
|
||||
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;
|
||||
};
|
||||
|
||||
var imports = {JSONToFile,RGBToHex,URLJoin,UUIDGeneratorBrowser,UUIDGeneratorNode,anagrams,arrayToHtmlList,ary,atob,average,averageBy,bind,bindKey,bottomVisible,btoa,byteSize,call,capitalize,capitalizeEveryWord,castArray,chainAsync,chunk,clampNumber,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,composeRight,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,decapitalize,deepClone,deepFlatten,defaults,defer,delay,detectDeviceType,difference,differenceBy,differenceWith,digitize,distance,dropElements,dropRight,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findKey,findLast,findLastIndex,findLastKey,flatten,flip,forEachRight,forOwn,forOwnRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,get,getDaysDiffBetweenDates,getScrollPosition,getStyle,getType,getURLParameters,groupBy,hammingDistance,hasClass,hasFlags,hashBrowser,hashNode,head,hexToRGB,hide,httpGet,httpPost,httpsRedirect,inRange,indexOfAll,initial,initialize2DArray,initializeArrayWithRange,initializeArrayWithRangeRight,initializeArrayWithValues,intersection,intersectionBy,intersectionWith,invertKeyValues,is,isAbsoluteURL,isArrayLike,isBoolean,isDivisible,isEmpty,isEven,isFunction,isLowerCase,isNil,isNull,isNumber,isObject,isObjectLike,isPlainObject,isPrime,isPrimitive,isPromiseLike,isSorted,isString,isSymbol,isTravisCI,isUndefined,isUpperCase,isValidJSON,join,last,lcm,longestItem,lowercaseKeys,luhnCheck,mapKeys,mapObject,mapValues,mask,matches,matchesWith,maxBy,maxN,median,memoize,merge,minBy,minN,negate,nthArg,nthElement,objectFromPairs,objectToPairs,observeMutations,off,omit,omitBy,on,onUserInputChange,once,orderBy,over,palindrome,parseCookie,partial,partialRight,partition,percentile,pick,pickBy,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,redirect,reduceSuccessive,reduceWhich,reducedFilter,remove,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,sortedLastIndex,splitLines,spreadOver,standardDeviation,sum,sumBy,sumPower,symmetricDifference,symmetricDifferenceBy,symmetricDifferenceWith,tail,take,takeRight,timeTaken,times,toCamelCase,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unary,unescapeHTML,unfold,union,unionBy,unionWith,uniqueElements,untildify,unzip,unzipWith,validateNumber,without,words,xProd,yesNo,zip,zipObject,zipWith,}
|
||||
|
||||
return imports;
|
||||
|
||||
|
||||
2
dist/_30s.min.js
vendored
2
dist/_30s.min.js
vendored
File diff suppressed because one or more lines are too long
273
docs/index.html
273
docs/index.html
File diff suppressed because one or more lines are too long
@ -57,7 +57,6 @@ try {
|
||||
})
|
||||
);
|
||||
tagDbStats = Object.entries(tagDbData)
|
||||
.sort((a, b) => a[1][0].localeCompare(b[1][0]))
|
||||
.reduce((acc, val) => {
|
||||
val[1].forEach(v => acc.hasOwnProperty(v) ? acc[v]++ : (acc[v] = 1));
|
||||
return acc;
|
||||
@ -89,7 +88,7 @@ try {
|
||||
}
|
||||
// Log statistics for the tag_database file
|
||||
console.log(`\n${chalk.bgWhite(chalk.black('=== TAG STATS ==='))}`);
|
||||
for (let tagData of Object.entries(tagDbStats).filter(v => v[0] !== 'undefined'))
|
||||
for (let tagData of Object.entries(tagDbStats).filter(v => v[0] !== 'undefined').sort((a,b) => a[0].localeCompare(b[0])))
|
||||
console.log(`${chalk.green(tagData[0])}: ${tagData[1]} snippets`);
|
||||
console.log(
|
||||
`${chalk.blue("New untagged snippets (will be tagged as 'uncategorized'):")} ${missingTags}\n`
|
||||
|
||||
@ -23,7 +23,7 @@ const snippetFiles = [];
|
||||
|
||||
const snippetFilesActive = fs.readdirSync(SNIPPETS_ACTIVE, 'utf8').map(fileName => fileName.slice(0, -3));
|
||||
const snippetFilesArchive = fs.readdirSync(SNIPPETS_ARCHIVE, 'utf8')
|
||||
.filter(fileName => !fileName.includes('README')) // -> Filters out main README.md file in Archieve which isn't a snippet
|
||||
.filter(fileName => !fileName.includes('README')) // -> Filters out main README.md file in Archieve which isn't a snippet
|
||||
.map(fileName => fileName.slice(0, -3));
|
||||
|
||||
snippetFiles.push(...snippetFilesActive);
|
||||
@ -46,35 +46,35 @@ snippetFiles
|
||||
const fileCode = fileData.slice(fileData.search(/```\s*js/i), fileData.lastIndexOf('```') + 3);
|
||||
// Split code based on code markers
|
||||
const blockMarkers = fileCode
|
||||
.split('\n')
|
||||
.map((line, lineIndex) => (line.slice(0, 3) === '```' ? lineIndex : '//CLEAR//'))
|
||||
.filter(x => !(x === '//CLEAR//'));
|
||||
.split('\n')
|
||||
.map((line, lineIndex) => (line.slice(0, 3) === '```' ? lineIndex : '//CLEAR//'))
|
||||
.filter(x => !(x === '//CLEAR//'));
|
||||
// Grab snippet function based on code markers
|
||||
const fileFunction = fileCode
|
||||
.split('\n')
|
||||
.map(line => line.trim())
|
||||
.filter((_, i) => blockMarkers[0] < i && i < blockMarkers[1]);
|
||||
.split('\n')
|
||||
.map(line => line.trim())
|
||||
.filter((_, i) => blockMarkers[0] < i && i < blockMarkers[1]);
|
||||
// Grab snippet example based on code markers
|
||||
const fileExample = fileCode
|
||||
.split('\n')
|
||||
.map(line => line.trim())
|
||||
.filter((_, i) => blockMarkers[2] < i && i < blockMarkers[3]);
|
||||
.split('\n')
|
||||
.map(line => line.trim())
|
||||
.filter((_, i) => blockMarkers[2] < i && i < blockMarkers[3]);
|
||||
|
||||
// Export template for snippetName.js
|
||||
const exportFile = `${fileFunction.join('\n')}\n module.exports = ${fileName}`;
|
||||
const exportFile = `${fileFunction.join('\n')}\nmodule.exports = ${fileName}`.trim();
|
||||
|
||||
// Export template for snippetName.test.js which generates a example test & other information
|
||||
const exportTest = [
|
||||
`const test = require('tape');`,
|
||||
`const ${fileName} = require('./${fileName}.js');`,
|
||||
`\ntest('Testing ${fileName}', (t) => {`,
|
||||
`\t//For more information on all the methods supported by tape\n\t//Please go to https://github.com/substack/tape`,
|
||||
`\tt.true(typeof ${fileName} === 'function', '${fileName} is a Function');`,
|
||||
`\t//t.deepEqual(${fileName}(args..), 'Expected');`,
|
||||
`\t//t.equal(${fileName}(args..), 'Expected');`,
|
||||
`\t//t.false(${fileName}(args..), 'Expected');`,
|
||||
`\t//t.throws(${fileName}(args..), 'Expected');`,
|
||||
`\tt.end();`,
|
||||
` //For more information on all the methods supported by tape\n //Please go to https://github.com/substack/tape`,
|
||||
` t.true(typeof ${fileName} === 'function', '${fileName} is a Function');`,
|
||||
` //t.deepEqual(${fileName}(args..), 'Expected');`,
|
||||
` //t.equal(${fileName}(args..), 'Expected');`,
|
||||
` //t.false(${fileName}(args..), 'Expected');`,
|
||||
` //t.throws(${fileName}(args..), 'Expected');`,
|
||||
` t.end();`,
|
||||
`});`
|
||||
].join('\n');
|
||||
|
||||
|
||||
14
snippets/ary.md
Normal file
14
snippets/ary.md
Normal file
@ -0,0 +1,14 @@
|
||||
### 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.slice(0,n)` and the spread operator (`...`).
|
||||
|
||||
```js
|
||||
const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
|
||||
```
|
||||
|
||||
```js
|
||||
const firstTwoMax = ary(Math.max, 2);
|
||||
[[2, 6, 'a'], [8, 4, 6], [10]].map(x => firstTwoMax(...x)); // [6, 8, 10]
|
||||
```
|
||||
22
snippets/bind.md
Normal file
22
snippets/bind.md
Normal file
@ -0,0 +1,22 @@
|
||||
### bind
|
||||
|
||||
Creates a function that invokes `fn` with a given context, optionally adding any additional supplied parameters to the beginning of the arguments.
|
||||
|
||||
Return a `function` that uses `Function.apply()` to apply the given `context` to `fn`.
|
||||
Use `Array.concat()` to prepend any additional supplied parameters to the arguments.
|
||||
|
||||
```js
|
||||
const bind = (fn, context, ...args) =>
|
||||
function() {
|
||||
return fn.apply(context, args.concat(...arguments));
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
function greet(greeting, punctuation) {
|
||||
return greeting + ' ' + this.user + punctuation;
|
||||
}
|
||||
const freddy = { user: 'fred' };
|
||||
const freddyBound = bind(greet, freddy);
|
||||
console.log(freddyBound('hi', '!')); // 'hi fred!'
|
||||
```
|
||||
24
snippets/bindKey.md
Normal file
24
snippets/bindKey.md
Normal file
@ -0,0 +1,24 @@
|
||||
### bindKey
|
||||
|
||||
Creates a function that invokes the method at a given key of an object, optionally adding any additional supplied parameters to the beginning of the arguments.
|
||||
|
||||
Return a `function` that uses `Function.apply()` to bind `context[fn]` to `context`.
|
||||
Use `Array.concat()` to prepend any additional supplied parameters to the arguments.
|
||||
|
||||
```js
|
||||
const bindKey = (context, fn, ...args) =>
|
||||
function() {
|
||||
return context[fn].apply(context, args.concat(...arguments));
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
const freddy = {
|
||||
user: 'fred',
|
||||
greet: function(greeting, punctuation) {
|
||||
return greeting + ' ' + this.user + punctuation;
|
||||
}
|
||||
};
|
||||
const freddyBound = bindKey(freddy, 'greet');
|
||||
console.log(freddyBound('hi', '!')); // 'hi fred!'
|
||||
```
|
||||
14
snippets/castArray.md
Normal file
14
snippets/castArray.md
Normal file
@ -0,0 +1,14 @@
|
||||
### castArray
|
||||
|
||||
Casts the provided value as an array if it's not one.
|
||||
|
||||
Use `Array.isArray()` to determine if `val` is an array and return it as-is or encapsulated in an array accordingly.
|
||||
|
||||
```js
|
||||
const castArray = val => (Array.isArray(val) ? val : [val]);
|
||||
```
|
||||
|
||||
```js
|
||||
castArray('foo'); // ['foo']
|
||||
castArray([1]); // [1]
|
||||
```
|
||||
17
snippets/composeRight.md
Normal file
17
snippets/composeRight.md
Normal file
@ -0,0 +1,17 @@
|
||||
### composeRight
|
||||
|
||||
Performs left-to-right function composition.
|
||||
|
||||
Use `Array.reduce()` to perform left-to-right function composition.
|
||||
The first (leftmost) function can accept one or more arguments; the remaining functions must be unary.
|
||||
|
||||
```js
|
||||
const composeRight = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
|
||||
```
|
||||
|
||||
```js
|
||||
const add = (x, y) => x + y;
|
||||
const square = x => x * x;
|
||||
const addAndSquare = composeRight(add, square);
|
||||
addAndSquare(1, 2); // 9
|
||||
```
|
||||
22
snippets/deepClone.md
Normal file
22
snippets/deepClone.md
Normal file
@ -0,0 +1,22 @@
|
||||
### deepClone
|
||||
|
||||
Creates a deep clone of an object.
|
||||
|
||||
Use recursion.
|
||||
Use `Object.assign()` and an empty object (`{}`) to create a shallow clone of the original.
|
||||
Use `Object.keys()` and `Array.forEach()` to determine which key-value pairs need to be deep cloned.
|
||||
|
||||
```js
|
||||
const 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;
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
const a = { foo: 'bar', obj: { a: 1, b: 2 } };
|
||||
const b = deepClone(a); // a !== b, a.obj !== b.obj
|
||||
```
|
||||
20
snippets/delay.md
Normal file
20
snippets/delay.md
Normal file
@ -0,0 +1,20 @@
|
||||
### delay
|
||||
|
||||
Invokes the provided function after `wait` milliseconds.
|
||||
|
||||
Use `setTimeout()` to delay execution of `fn`.
|
||||
Use the spread (`...`) operator to supply the function with an arbitrary number of arguments.
|
||||
|
||||
```js
|
||||
const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
|
||||
```
|
||||
|
||||
```js
|
||||
delay(
|
||||
function(text) {
|
||||
console.log(text);
|
||||
},
|
||||
1000,
|
||||
'later'
|
||||
); // Logs 'later' after one second.
|
||||
```
|
||||
17
snippets/differenceBy.md
Normal file
17
snippets/differenceBy.md
Normal file
@ -0,0 +1,17 @@
|
||||
### 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`, then use `Array.filter()` in combination with `fn` on `a` to only keep values not contained in the previously created set.
|
||||
|
||||
```js
|
||||
const differenceBy = (a, b, fn) => {
|
||||
const s = new Set(b.map(v => fn(v)));
|
||||
return a.filter(x => !s.has(fn(x)));
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [1.2]
|
||||
differenceBy([{ x: 2 }, { x: 1 }], [{ x: 1 }], v => v.x); // [ { x: 2 } ]
|
||||
```
|
||||
20
snippets/findKey.md
Normal file
20
snippets/findKey.md
Normal file
@ -0,0 +1,20 @@
|
||||
### findKey
|
||||
|
||||
Returns 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.find()` to test the provided function for each key-value pair. The callback receives three arguments - the value, the key and the object.
|
||||
|
||||
```js
|
||||
const findKey = (obj, fn) => Object.keys(obj).find(key => fn(obj[key], key, obj));
|
||||
```
|
||||
|
||||
```js
|
||||
findKey(
|
||||
{
|
||||
barney: { age: 36, active: true },
|
||||
fred: { age: 40, active: false },
|
||||
pebbles: { age: 1, active: true }
|
||||
},
|
||||
o => o['active']
|
||||
); // 'barney'
|
||||
```
|
||||
@ -5,7 +5,7 @@ Returns the last element for which the provided function returns a truthy value.
|
||||
Use `Array.filter()` to remove elements for which `fn` returns falsey values, `Array.slice(-1)` to get the last one.
|
||||
|
||||
```js
|
||||
const findLast = (arr, fn) => arr.filter(fn).slice(-1);
|
||||
const findLast = (arr, fn) => arr.filter(fn).slice(-1)[0];
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
18
snippets/findLastIndex.md
Normal file
18
snippets/findLastIndex.md
Normal file
@ -0,0 +1,18 @@
|
||||
### findLastIndex
|
||||
|
||||
Returns the index of the last element for which the provided function returns a truthy value.
|
||||
|
||||
Use `Array.map()` to map each element to an array with its index and value.
|
||||
Use `Array.filter()` to remove elements for which `fn` returns falsey values, `Array.slice(-1)` to get the last one.
|
||||
|
||||
```js
|
||||
const findLastIndex = (arr, fn) =>
|
||||
arr
|
||||
.map((val, i) => [i, val])
|
||||
.filter(val => fn(val[1], val[0], arr))
|
||||
.slice(-1)[0][0];
|
||||
```
|
||||
|
||||
```js
|
||||
findLastIndex([1, 2, 3, 4], n => n % 2 === 1); // 2 (index of the value 3)
|
||||
```
|
||||
23
snippets/findLastKey.md
Normal file
23
snippets/findLastKey.md
Normal file
@ -0,0 +1,23 @@
|
||||
### findLastKey
|
||||
|
||||
Returns 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, `Array.reverse()` to reverse their order and `Array.find()` to test the provided function for each key-value pair. The callback receives three arguments - the value, the key and the object.
|
||||
|
||||
```js
|
||||
const findLastKey = (obj, fn) =>
|
||||
Object.keys(obj)
|
||||
.reverse()
|
||||
.find(key => fn(obj[key], key, obj));
|
||||
```
|
||||
|
||||
```js
|
||||
findLastKey(
|
||||
{
|
||||
barney: { age: 36, active: true },
|
||||
fred: { age: 40, active: false },
|
||||
pebbles: { age: 1, active: true }
|
||||
},
|
||||
o => o['active']
|
||||
); // 'pebbles'
|
||||
```
|
||||
16
snippets/intersectionBy.md
Normal file
16
snippets/intersectionBy.md
Normal file
@ -0,0 +1,16 @@
|
||||
### intersectionBy
|
||||
|
||||
Returns a list of elements that exist in both arrays, after applying the provided function to each array element of both.
|
||||
|
||||
Create a `Set` by applying `fn` to all elements in `b`, then use `Array.filter()` on `a` to only keep elements, which produce values contained in `b` when `fn` is applied to them.
|
||||
|
||||
```js
|
||||
const intersectionBy = (a, b, fn) => {
|
||||
const s = new Set(b.map(x => fn(x)));
|
||||
return a.filter(x => s.has(fn(x)));
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [2.1]
|
||||
```
|
||||
13
snippets/intersectionWith.md
Normal file
13
snippets/intersectionWith.md
Normal file
@ -0,0 +1,13 @@
|
||||
### intersectionWith
|
||||
|
||||
Returns a list of elements that exist in both arrays, using a provided comparator function.
|
||||
|
||||
Use `Array.filter()` and `Array.findIndex()` in combination with the provided comparator to determine intersecting values.
|
||||
|
||||
```js
|
||||
const intersectionWith = (a, b, comp) => a.filter(x => b.findIndex(y => comp(x, y)) !== -1);
|
||||
```
|
||||
|
||||
```js
|
||||
intersectionWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0, 3.9], (a, b) => Math.round(a) === Math.round(b)); // [1.5, 3, 0]
|
||||
```
|
||||
@ -1,17 +1,21 @@
|
||||
### invertKeyValues
|
||||
|
||||
Inverts the key-value pairs of an object, without mutating it.
|
||||
Inverts the key-value pairs of an object, without mutating it. The corresponding inverted value of each inverted key is an array of keys responsible for generating the inverted value. If a function is supplied, it is applied to each inverted key.
|
||||
|
||||
Use `Object.keys()` and `Array.reduce()` to invert the key-value pairs of an object.
|
||||
Use `Object.keys()` and `Array.reduce()` to invert the key-value pairs of an object and apply the function provided (if any).
|
||||
Omit the second argument, `fn`, to get the inverted keys without applying a function to them.
|
||||
|
||||
```js
|
||||
const invertKeyValues = obj =>
|
||||
const invertKeyValues = (obj, fn) =>
|
||||
Object.keys(obj).reduce((acc, key) => {
|
||||
acc[obj[key]] = key;
|
||||
const val = fn ? fn(obj[key]) : obj[key];
|
||||
acc[val] = acc[val] || [];
|
||||
acc[val].push(key);
|
||||
return acc;
|
||||
}, {});
|
||||
```
|
||||
|
||||
```js
|
||||
invertKeyValues({ name: 'John', age: 20 }); // { 20: 'age', John: 'name' }
|
||||
invertKeyValues({ a: 1, b: 2, c: 1 }); // { 1: [ 'a', 'c' ], 2: [ 'b' ] }
|
||||
invertKeyValues({ a: 1, b: 2, c: 1 }, value => 'group' + value); // { group1: [ 'a', 'c' ], group2: [ 'b' ] }
|
||||
```
|
||||
|
||||
22
snippets/isEmpty.md
Normal file
22
snippets/isEmpty.md
Normal file
@ -0,0 +1,22 @@
|
||||
### isEmpty
|
||||
|
||||
Returns true if the a value is an empty object, collection, map or set, has no enumerable properties or is any type that is not considered a collection.
|
||||
|
||||
Check if the provided value is `null` or if its `length` is equal to `0`.
|
||||
|
||||
```js
|
||||
const isEmpty = val => val == null || !(Object.keys(val) || val).length;
|
||||
```
|
||||
|
||||
```js
|
||||
isEmpty(new Map()); // true
|
||||
isEmpty(new Set()); // true
|
||||
isEmpty([]); // true
|
||||
isEmpty({}); // true
|
||||
isEmpty(''); // true
|
||||
isEmpty([1, 2]); // false
|
||||
isEmpty({ a: 1, b: 2 }); // false
|
||||
isEmpty('text'); // false
|
||||
isEmpty(123); // true - type is not considered a collection
|
||||
isEmpty(true); // true - type is not considered a collection
|
||||
```
|
||||
16
snippets/isObjectLike.md
Normal file
16
snippets/isObjectLike.md
Normal file
@ -0,0 +1,16 @@
|
||||
### isObjectLike
|
||||
|
||||
Checks if a value is object-like.
|
||||
|
||||
Check if the provided value is not `null` and its `typeof` is equal to `'object'`.
|
||||
|
||||
```js
|
||||
const isObjectLike = val => val !== null && typeof val === 'object';
|
||||
```
|
||||
|
||||
```js
|
||||
isObjectLike({}); // true
|
||||
isObjectLike([1, 2, 3]); // true
|
||||
isObjectLike(x => x); // false
|
||||
isObjectLike(null); // false
|
||||
```
|
||||
15
snippets/matches.md
Normal file
15
snippets/matches.md
Normal file
@ -0,0 +1,15 @@
|
||||
### matches
|
||||
|
||||
Compares two objects to determine if the first one contains equivalent property values to the second one.
|
||||
|
||||
Use `Object.keys(source)` to get all the keys of the second object, then `Array.every()`, `Object.hasOwnProperty()` and strict comparison to determine if all keys exist in the first object and have the same values.
|
||||
|
||||
```js
|
||||
const matches = (obj, source) =>
|
||||
Object.keys(source).every(key => obj.hasOwnProperty(key) && obj[key] === source[key]);
|
||||
```
|
||||
|
||||
```js
|
||||
matches({ age: 25, hair: 'long', beard: true }, { hair: 'long', beard: true }); // true
|
||||
matches({ hair: 'long', beard: true }, { age: 25, hair: 'long', beard: true }); // false
|
||||
```
|
||||
25
snippets/matchesWith.md
Normal file
25
snippets/matchesWith.md
Normal file
@ -0,0 +1,25 @@
|
||||
### matchesWith
|
||||
|
||||
Compares two objects to determine if the first one contains equivalent property values to the second one, based on a provided function.
|
||||
|
||||
Use `Object.keys(source)` to get all the keys of the second object, then `Array.every()`, `Object.hasOwnProperty()` and the provided function to determine if all keys exist in the first object and have equivalent values.
|
||||
If no function is provided, the values will be compared using the equality operator.
|
||||
|
||||
```js
|
||||
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]
|
||||
);
|
||||
```
|
||||
|
||||
```js
|
||||
const isGreeting = val => /^h(?:i|ello)$/.test(val);
|
||||
matchesWith(
|
||||
{ greeting: 'hello' },
|
||||
{ greeting: 'hi' },
|
||||
(oV, sV) => isGreeting(oV) && isGreeting(sV)
|
||||
); // true
|
||||
```
|
||||
@ -9,6 +9,6 @@ const minBy = (arr, fn) => Math.min(...arr.map(typeof fn === 'function' ? fn : v
|
||||
```
|
||||
|
||||
```js
|
||||
minBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 8
|
||||
minBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 8
|
||||
minBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 2
|
||||
minBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 2
|
||||
```
|
||||
|
||||
17
snippets/nthArg.md
Normal file
17
snippets/nthArg.md
Normal file
@ -0,0 +1,17 @@
|
||||
### nthArg
|
||||
|
||||
Creates a function that gets the argument at index `n`. If `n` is negative, the nth argument from the end is returned.
|
||||
|
||||
Use `Array.slice()` to get the desired argument at index `n`.
|
||||
|
||||
```js
|
||||
const nthArg = n => (...args) => args.slice(n)[0];
|
||||
```
|
||||
|
||||
```js
|
||||
const third = nthArg(2);
|
||||
third(1, 2, 3); // 3
|
||||
third(1, 2); // undefined
|
||||
const last = nthArg(-1);
|
||||
last(1, 2, 3, 4, 5); // 5
|
||||
```
|
||||
@ -14,3 +14,4 @@ const omitBy = (obj, fn) =>
|
||||
|
||||
```js
|
||||
omitBy({ a: 1, b: '2', c: 3 }, x => typeof x === 'number'); // { b: '2' }
|
||||
```
|
||||
|
||||
14
snippets/over.md
Normal file
14
snippets/over.md
Normal file
@ -0,0 +1,14 @@
|
||||
### over
|
||||
|
||||
Creates a function that invokes each provided function with the arguments it receives and returns the results.
|
||||
|
||||
Use `Array.map()` and `Function.apply()` to apply each function to the given arguments.
|
||||
|
||||
```js
|
||||
const over = (...fns) => (...args) => fns.map(fn => fn.apply(null, args));
|
||||
```
|
||||
|
||||
```js
|
||||
const minMax = over(Math.min, Math.max);
|
||||
minMax(1, 2, 3, 4, 5); // [1,5]
|
||||
```
|
||||
17
snippets/partial.md
Normal file
17
snippets/partial.md
Normal file
@ -0,0 +1,17 @@
|
||||
### partial
|
||||
|
||||
Creates a function that invokes `fn` with `partials` prepended to the arguments it receives.
|
||||
|
||||
Use the spread operator (`...`) to prepend `partials` to the list of arguments of `fn`.
|
||||
|
||||
```js
|
||||
const partial = (fn, ...partials) => (...args) => fn(...partials, ...args);
|
||||
```
|
||||
|
||||
```js
|
||||
function greet(greeting, name) {
|
||||
return greeting + ' ' + name + '!';
|
||||
}
|
||||
const greetHello = partial(greet, 'Hello');
|
||||
greetHello('John'); // 'Hello John!'
|
||||
```
|
||||
17
snippets/partialRight.md
Normal file
17
snippets/partialRight.md
Normal file
@ -0,0 +1,17 @@
|
||||
### partialRight
|
||||
|
||||
Creates a function that invokes `fn` with `partials` appended to the arguments it receives.
|
||||
|
||||
Use the spread operator (`...`) to append `partials` to the list of arguments of `fn`.
|
||||
|
||||
```js
|
||||
const partialRight = (fn, ...partials) => (...args) => fn(...args, ...partials);
|
||||
```
|
||||
|
||||
```js
|
||||
function greet(greeting, name) {
|
||||
return greeting + ' ' + name + '!';
|
||||
}
|
||||
const greetJohn = partialRight(greet, 'John');
|
||||
greetJohn('Hello'); // 'Hello John!'
|
||||
```
|
||||
14
snippets/reduceSuccessive.md
Normal file
14
snippets/reduceSuccessive.md
Normal file
@ -0,0 +1,14 @@
|
||||
### reduceSuccessive
|
||||
|
||||
Applies a function against an accumulator and each element in the array (from left to right), returning an array of successively reduced values.
|
||||
|
||||
Use `Array.reduce()` to apply the given function to the given array, storing each new result.
|
||||
|
||||
```js
|
||||
const reduceSuccessive = (arr, fn, acc) =>
|
||||
arr.reduce((res, val, i, arr) => (res.push(fn(res.slice(-1)[0], val, i, arr)), res), [acc]);
|
||||
```
|
||||
|
||||
```js
|
||||
reduceSuccessive([1, 2, 3, 4, 5, 6], (acc, val) => acc + val, 0); // [0, 1, 3, 6, 10, 15, 21]
|
||||
```
|
||||
20
snippets/reduceWhich.md
Normal file
20
snippets/reduceWhich.md
Normal file
@ -0,0 +1,20 @@
|
||||
### reduceWhich
|
||||
|
||||
Returns the minimum/maximum value of an array, after applying the provided function to set comparing rule.
|
||||
|
||||
Use `Array.reduce()` in combination with the `comparator` function to get the appropriate element in the array.
|
||||
You can omit the second parameter, `comparator`, to use the default one that returns the minimum element in the array.
|
||||
|
||||
```js
|
||||
const reduceWhich = (arr, comparator = (a, b) => a - b) =>
|
||||
arr.reduce((a, b) => (comparator(a, b) >= 0 ? b : a));
|
||||
```
|
||||
|
||||
```js
|
||||
reduceWhich([1, 3, 2]); // 1
|
||||
reduceWhich([1, 3, 2], (a, b) => b - a); // 3
|
||||
reduceWhich(
|
||||
[{ name: 'Tom', age: 12 }, { name: 'Jack', age: 18 }, { name: 'Lucy', age: 9 }],
|
||||
(a, b) => a.age - b.age
|
||||
); // {name: "Lucy", age: 9}
|
||||
```
|
||||
22
snippets/sortedLastIndex.md
Normal file
22
snippets/sortedLastIndex.md
Normal file
@ -0,0 +1,22 @@
|
||||
### sortedLastIndex
|
||||
|
||||
Returns the highest index at which value should be inserted into array in order to maintain its sort order.
|
||||
|
||||
Check if the array is sorted in descending order (loosely).
|
||||
Use `Array.map()` to map each element to an array with its index and value.
|
||||
Use `Array.filter()` to find all possible positions where the element could be inserted, `Array.slice(-1)` to get the last one.
|
||||
|
||||
```js
|
||||
const sortedLastIndex = (arr, n) => {
|
||||
const isDescending = arr[0] > arr[arr.length - 1];
|
||||
const index = arr
|
||||
.map((val, i) => [i, val])
|
||||
.filter(el => (isDescending ? n >= el[1] : n >= el[1]))
|
||||
.slice(-1)[0][0];
|
||||
return index === -1 ? arr.length : index;
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
sortedLastIndex([10, 20, 30, 30, 40], 30); // 3
|
||||
```
|
||||
17
snippets/symmetricDifferenceBy.md
Normal file
17
snippets/symmetricDifferenceBy.md
Normal file
@ -0,0 +1,17 @@
|
||||
### symmetricDifferenceBy
|
||||
|
||||
Returns the symmetric difference between two arrays, after applying the provided function to each array element of both.
|
||||
|
||||
Create a `Set` by applying `fn` to each array's elements, then use `Array.filter()` on each of them to only keep values not contained in the other.
|
||||
|
||||
```js
|
||||
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)))];
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
symmetricDifferenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [ 1.2, 3.4 ]
|
||||
```
|
||||
20
snippets/symmetricDifferenceWith.md
Normal file
20
snippets/symmetricDifferenceWith.md
Normal file
@ -0,0 +1,20 @@
|
||||
### symmetricDifferenceWith
|
||||
|
||||
Returns the symmetric difference between two arrays, using a provided function as a comparator.
|
||||
|
||||
Use `Array.filter()` and `Array.findIndex()` to find the appropriate values.
|
||||
|
||||
```js
|
||||
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)
|
||||
];
|
||||
```
|
||||
|
||||
```js
|
||||
symmetricDifferenceWith(
|
||||
[1, 1.2, 1.5, 3, 0],
|
||||
[1.9, 3, 0, 3.9],
|
||||
(a, b) => Math.round(a) === Math.round(b)
|
||||
); // [1, 1.2, 3.9]
|
||||
```
|
||||
19
snippets/times.md
Normal file
19
snippets/times.md
Normal file
@ -0,0 +1,19 @@
|
||||
### times
|
||||
|
||||
Iterates over a callback `n` times
|
||||
|
||||
Use `Function.call()` to call `fn` `n` times or until it returns `false`.
|
||||
Omit the last argument, `context`, to use an `undefined` object (or the global object in non-strict mode).
|
||||
|
||||
```js
|
||||
const times = (n, fn, context = undefined) => {
|
||||
let i = 0;
|
||||
while (fn.call(context, i) !== false && ++i < n) {}
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
var output = '';
|
||||
times(5, i => (output += i));
|
||||
console.log(output); // 01234
|
||||
```
|
||||
@ -1,10 +1,16 @@
|
||||
### tomorrow
|
||||
|
||||
Results in a string representation of tomorrow's date.
|
||||
Use `new Date()` to get today's date, adding `86400000` of seconds to it(24 hours), using `Date.toISOString()` to convert Date object to string.
|
||||
Use `new Date()` to get today's date, adding one day using `Date.getDate()` and `Date.setDate()`, and converting the Date object to a string.
|
||||
|
||||
```js
|
||||
const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0];
|
||||
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')}`;
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
13
snippets/unary.md
Normal file
13
snippets/unary.md
Normal file
@ -0,0 +1,13 @@
|
||||
### unary
|
||||
|
||||
Creates a function that accepts up to one argument, ignoring any additional arguments.
|
||||
|
||||
Call the provided function, `fn`, with just the first argument given.
|
||||
|
||||
```js
|
||||
const unary = fn => val => fn(val);
|
||||
```
|
||||
|
||||
```js
|
||||
['6', '8', '10'].map(unary(parseInt)); // [6, 8, 10]
|
||||
```
|
||||
20
snippets/unfold.md
Normal file
20
snippets/unfold.md
Normal file
@ -0,0 +1,20 @@
|
||||
### unfold
|
||||
|
||||
Builds an array, using an iterator function and an initial seed value.
|
||||
|
||||
Use a `while` loop and `Array.push()` to call the function repeatedly until it returns `false`.
|
||||
The iterator function accepts one argument (`seed`) and must always return an array with two elements ([`value`, `nextSeed`]) or `false` to terminate.
|
||||
|
||||
```js
|
||||
const unfold = (fn, seed) => {
|
||||
let result = [],
|
||||
val = [null, seed];
|
||||
while ((val = fn(val[1]))) result.push(val[0]);
|
||||
return result;
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
var f = n => (n > 50 ? false : [-n, n + 10]);
|
||||
unfold(f, 10); // [-10, -20, -30, -40, -50]
|
||||
```
|
||||
18
snippets/unionBy.md
Normal file
18
snippets/unionBy.md
Normal file
@ -0,0 +1,18 @@
|
||||
### unionBy
|
||||
|
||||
Returns every element that exists in any of the two arrays once, after applying the provided function to each array element of both.
|
||||
|
||||
Create a `Set` by applying all `fn` to all values of `a`.
|
||||
Create a `Set` from `a` and all elements in `b` whose value, after applying `fn` does not match a value in the previously created set.
|
||||
Return the last set converted to an array.
|
||||
|
||||
```js
|
||||
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)))]));
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
unionBy([2.1], [1.2, 2.3], Math.floor); // [2.1, 1.2]
|
||||
```
|
||||
14
snippets/unionWith.md
Normal file
14
snippets/unionWith.md
Normal file
@ -0,0 +1,14 @@
|
||||
### unionWith
|
||||
|
||||
Returns every element that exists in any of the two arrays once, using a provided comparator function.
|
||||
|
||||
Create a `Set` with all values of `a` and values in `b` for which the comparator finds no matches in `a`, using `Array.findIndex()`.
|
||||
|
||||
```js
|
||||
const unionWith = (a, b, comp) =>
|
||||
Array.from(new Set([...a, ...b.filter(x => a.findIndex(y => comp(x, y)) === -1)]));
|
||||
```
|
||||
|
||||
```js
|
||||
unionWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0, 3.9], (a, b) => Math.round(a) === Math.round(b)); // [1, 1.2, 1.5, 3, 0, 3.9]
|
||||
```
|
||||
21
snippets/unzip.md
Normal file
21
snippets/unzip.md
Normal file
@ -0,0 +1,21 @@
|
||||
### unzip
|
||||
|
||||
Creates an array of arrays, ungrouping the elements in an array produced by [zip](#zip).
|
||||
|
||||
Use `Math.max.apply()` to get the longest subarray in the array, `Array.map()` to make each element an array.
|
||||
Use `Array.reduce()` and `Array.forEach()` to map grouped values to individual arrays.
|
||||
|
||||
```js
|
||||
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 => [])
|
||||
);
|
||||
```
|
||||
|
||||
```js
|
||||
unzip([['a', 1, true], ['b', 2, false]]); //[['a', 'b'], [1, 2], [true, false]]
|
||||
unzip([['a', 1, true], ['b', 2]]); //[['a', 'b'], [1, 2], [true]]
|
||||
```
|
||||
23
snippets/unzipWith.md
Normal file
23
snippets/unzipWith.md
Normal file
@ -0,0 +1,23 @@
|
||||
### unzipWith
|
||||
|
||||
Creates an array of elements, ungrouping the elements in an array produced by [zip](#zip) and applying the provided function.
|
||||
|
||||
Use `Math.max.apply()` to get the longest subarray in the array, `Array.map()` to make each element an array.
|
||||
Use `Array.reduce()` and `Array.forEach()` to map grouped values to individual arrays.
|
||||
Use `Array.map()` and the spread operator (`...`) to apply `fn` to each individual group of elements.
|
||||
|
||||
```js
|
||||
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));
|
||||
```
|
||||
|
||||
```js
|
||||
unzipWith([[1, 10, 100], [2, 20, 200]], (...args) => args.reduce((acc, v) => acc + v, 0)); // [3, 30, 300]
|
||||
```
|
||||
13
snippets/xProd.md
Normal file
13
snippets/xProd.md
Normal file
@ -0,0 +1,13 @@
|
||||
### xProd
|
||||
|
||||
Creates a new array out of the two supplied by creating each possible pair from the arrays.
|
||||
|
||||
Use `Array.reduce()`, `Array.map()` and `Array.concat()` to produce every possible pair from the elements of the two arrays and save them in an array.
|
||||
|
||||
```js
|
||||
const xProd = (a, b) => a.reduce((acc, x) => acc.concat(b.map(y => [x, y])), []);
|
||||
```
|
||||
|
||||
```js
|
||||
xProd([1, 2], ['a', 'b']); // [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]
|
||||
```
|
||||
32
snippets/zipWith.md
Normal file
32
snippets/zipWith.md
Normal file
@ -0,0 +1,32 @@
|
||||
### zipWith
|
||||
|
||||
Creates an array of elements, grouped based on the position in the original arrays and using function as the last value to specify how grouped values should be combined.
|
||||
|
||||
Check if the last argument provided in a function.
|
||||
Use `Math.max()` to get the longest array in the arguments.
|
||||
Creates an array with that length as return value and use `Array.from()` with a map-function to create an array of grouped elements.
|
||||
If lengths of the argument-arrays vary, `undefined` is used where no value could be found.
|
||||
The function is invoked with the elements of each group `(...group)`.
|
||||
|
||||
```js
|
||||
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;
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
zipWith([1, 2], [10, 20], [100, 200], (a, b, c) => a + b + c); // [111,222]
|
||||
zipWith(
|
||||
[1, 2, 3],
|
||||
[10, 20],
|
||||
[100, 200],
|
||||
(a, b, c) => (a != null ? a : 'a') + (b != null ? b : 'b') + (c != null ? c : 'c')
|
||||
); // [111, 222, '3bc']
|
||||
```
|
||||
@ -9,18 +9,19 @@ These snippets, while useful and interesting, didn't quite make it into the repo
|
||||
* [`JSONToDate`](#jsontodate)
|
||||
* [`speechSynthesis`](#speechsynthesis)
|
||||
* [`binarySearch`](#binarysearch)
|
||||
* [`cleanObj`](#cleanobj)
|
||||
* [`collatz`](#collatz)
|
||||
* [`countVowels`](#countvowels)
|
||||
* [`factors`](#factors)
|
||||
* [`fibonacciCountUntilNum`](#fibonaccicountuntilnum)
|
||||
* [`fibonacciUntilNum`](#fibonacciuntilnum)
|
||||
* [`howManyTimes`](#howmanytimes)
|
||||
* [`httpDelete`](#httpdelete)
|
||||
* [`httpPut`](#httpput)
|
||||
* [`isArmstrongNumber`](#isarmstrongnumber)
|
||||
* [`quickSort`](#quicksort)
|
||||
* [`removeVowels`](#removevowels)
|
||||
* [`solveRPN`](#solverpn)
|
||||
* [`howManyTimes`](#howmanytimes)
|
||||
* [`fibonacciUntilNum`](#fibonacciuntilnum)
|
||||
|
||||
---
|
||||
|
||||
@ -111,6 +112,39 @@ binarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 21); // -1
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### cleanObj
|
||||
|
||||
Removes any properties except the ones specified from a JSON object.
|
||||
|
||||
Use `Object.keys()` method to loop over given JSON object and deleting keys that are not included in given array.
|
||||
If you pass a special key,`childIndicator`, it will search deeply apply the function to inner objects, too.
|
||||
|
||||
```js
|
||||
const cleanObj = (obj, keysToKeep = [], childIndicator) => {
|
||||
Object.keys(obj).forEach(key => {
|
||||
if (key === childIndicator) {
|
||||
cleanObj(obj[key], keysToKeep, childIndicator);
|
||||
} else if (!keysToKeep.includes(key)) {
|
||||
delete obj[key];
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
};
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Examples</summary>
|
||||
|
||||
```js
|
||||
const testObj = { a: 1, b: 2, children: { a: 1, b: 2 } };
|
||||
cleanObj(testObj, ['a'], 'children'); // { a: 1, children : { a: 1}}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### collatz
|
||||
|
||||
Applies the Collatz algorithm.
|
||||
@ -230,21 +264,26 @@ fibonacciCountUntilNum(10); // 7
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### fibonacciUntilNum
|
||||
### howManyTimes
|
||||
|
||||
Generates an array, containing the Fibonacci sequence, up until the nth term.
|
||||
Returns the number of times `num` can be divided by `divisor` (integer or fractional) without getting a fractional answer.
|
||||
Works for both negative and positive integers.
|
||||
|
||||
Create an empty array of the specific length, initializing the first two values (`0` and `1`).
|
||||
Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two.
|
||||
Uses a mathematical formula to calculate the length of the array required.
|
||||
If `divisor` is `-1` or `1` return `Infinity`.
|
||||
If `divisor` is `-0` or `0` return `0`.
|
||||
Otherwise, keep dividing `num` with `divisor` and incrementing `i`, while the result is an integer.
|
||||
Return the number of times the loop was executed, `i`.
|
||||
|
||||
```js
|
||||
const fibonacciUntilNum = num => {
|
||||
let n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2));
|
||||
return Array.from({ length: n }).reduce(
|
||||
(acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),
|
||||
[]
|
||||
);
|
||||
const howManyTimes = (num, divisor) => {
|
||||
if (divisor === 1 || divisor === -1) return Infinity;
|
||||
if (divisor === 0) return 0;
|
||||
let i = 0;
|
||||
while (Number.isInteger(num / divisor)) {
|
||||
i++;
|
||||
num = num / divisor;
|
||||
}
|
||||
return i;
|
||||
};
|
||||
```
|
||||
|
||||
@ -252,7 +291,10 @@ const fibonacciUntilNum = num => {
|
||||
<summary>Examples</summary>
|
||||
|
||||
```js
|
||||
fibonacciUntilNum(10); // [ 0, 1, 1, 2, 3, 5, 8 ]
|
||||
howManyTimes(100, 2); // 2
|
||||
howManyTimes(100, 2.5); // 2
|
||||
howManyTimes(100, 0); // 0
|
||||
howManyTimes(100, -1); // Infinity
|
||||
```
|
||||
|
||||
</details>
|
||||
@ -466,26 +508,21 @@ solveRPN('2 3 ^'); // 8
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### howManyTimes
|
||||
### fibonacciUntilNum
|
||||
|
||||
Returns the number of times `num` can be divided by `divisor` (integer or fractional) without getting a fractional answer.
|
||||
Works for both negative and positive integers.
|
||||
Generates an array, containing the Fibonacci sequence, up until the nth term.
|
||||
|
||||
If `divisor` is `-1` or `1` return `Infinity`.
|
||||
If `divisor` is `-0` or `0` return `0`.
|
||||
Otherwise, keep dividing `num` with `divisor` and incrementing `i`, while the result is an integer.
|
||||
Return the number of times the loop was executed, `i`.
|
||||
Create an empty array of the specific length, initializing the first two values (`0` and `1`).
|
||||
Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two.
|
||||
Uses a mathematical formula to calculate the length of the array required.
|
||||
|
||||
```js
|
||||
const howManyTimes = (num, divisor) => {
|
||||
if (divisor === 1 || divisor === -1) return Infinity;
|
||||
if (divisor === 0) return 0;
|
||||
let i = 0;
|
||||
while (Number.isInteger(num / divisor)) {
|
||||
i++;
|
||||
num = num / divisor;
|
||||
}
|
||||
return i;
|
||||
const fibonacciUntilNum = num => {
|
||||
let n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2));
|
||||
return Array.from({ length: n }).reduce(
|
||||
(acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),
|
||||
[]
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
@ -493,10 +530,7 @@ const howManyTimes = (num, divisor) => {
|
||||
<summary>Examples</summary>
|
||||
|
||||
```js
|
||||
howManyTimes(100, 2); // 2
|
||||
howManyTimes(100, 2.5); // 2
|
||||
howManyTimes(100, 0); // 0
|
||||
howManyTimes(100, -1); // Infinity
|
||||
fibonacciUntilNum(10); // [ 0, 1, 1, 2, 3, 5, 8 ]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
37
tag_database
37
tag_database
@ -1,14 +1,18 @@
|
||||
anagrams:string,recursion
|
||||
arrayToHtmlList:browser,array
|
||||
ary:adapter,function
|
||||
atob:node,string,utility
|
||||
average:math,array
|
||||
averageBy:math,array,function
|
||||
bind:function,object
|
||||
bindKey:function,object
|
||||
bottomVisible:browser
|
||||
btoa:node,string,utility
|
||||
byteSize:string
|
||||
call:adapter,function
|
||||
capitalize:string,array
|
||||
capitalizeEveryWord:string,regexp
|
||||
castArray:utility,array,type
|
||||
chainAsync:function
|
||||
chunk:array
|
||||
clampNumber:math
|
||||
@ -19,6 +23,7 @@ collectInto:adapter,function,array
|
||||
colorize:node,utility,string
|
||||
compact:array
|
||||
compose:function
|
||||
composeRight:function
|
||||
copyToClipboard:browser,string,advanced
|
||||
countBy:array,object
|
||||
countOccurrences:array
|
||||
@ -27,11 +32,14 @@ createEventHub:browser,event,advanced
|
||||
currentURL:browser,url
|
||||
curry:function,recursion
|
||||
decapitalize:string,array
|
||||
deepClone:object,recursion
|
||||
deepFlatten:array,recursion
|
||||
defaults:object
|
||||
defer:function
|
||||
delay:function
|
||||
detectDeviceType:browser
|
||||
difference:array,math
|
||||
differenceBy:array,function
|
||||
differenceWith:array,function
|
||||
digitize:math,array
|
||||
distance:math
|
||||
@ -47,7 +55,10 @@ extendHex:utility,string
|
||||
factorial:math,recursion
|
||||
fibonacci:math,array
|
||||
filterNonUnique:array
|
||||
findKey:object,function
|
||||
findLast:array
|
||||
findLastIndex:array,function
|
||||
findLastKey:object,function
|
||||
flatten:array
|
||||
flip:adapter,function
|
||||
forEachRight:array,function
|
||||
@ -85,12 +96,15 @@ initializeArrayWithRangeRight:array,math
|
||||
initializeArrayWithValues:array,math
|
||||
inRange:math
|
||||
intersection:array,math
|
||||
invertKeyValues:object
|
||||
intersectionBy:array,function
|
||||
intersectionWith:array,function
|
||||
invertKeyValues:object,function
|
||||
is:type,array,regexp
|
||||
isAbsoluteURL:string,utility,browser,url
|
||||
isArrayLike:type,array
|
||||
isBoolean:type
|
||||
isDivisible:math
|
||||
isEmpty:type,array,object,string
|
||||
isEven:math
|
||||
isFunction:type,function
|
||||
isLowerCase:string,utility
|
||||
@ -98,6 +112,7 @@ isNil:type
|
||||
isNull:type
|
||||
isNumber:type,math
|
||||
isObject:type,object
|
||||
isObjectLike:type,object
|
||||
isPlainObject:type,object
|
||||
isPrime:math
|
||||
isPrimitive:type,function,array,string
|
||||
@ -120,6 +135,8 @@ mapKeys:object,function
|
||||
mapObject:array,object
|
||||
mapValues:object,function
|
||||
mask:string,utility,regexp
|
||||
matches:object,type
|
||||
matchesWith:object,type,function
|
||||
maxBy:math,array,function
|
||||
maxN:array,math
|
||||
median:math,array
|
||||
@ -128,6 +145,7 @@ merge:object,array
|
||||
minBy:math,array,function
|
||||
minN:array,math
|
||||
negate:function
|
||||
nthArg:utility,function
|
||||
nthElement:array
|
||||
objectFromPairs:object,array
|
||||
objectToPairs:object,array
|
||||
@ -139,8 +157,11 @@ on:browser,event
|
||||
once:function
|
||||
onUserInputChange:browser,event,advanced
|
||||
orderBy:object,array
|
||||
over:adapter,function
|
||||
palindrome:string
|
||||
parseCookie:utility,string
|
||||
partial:function
|
||||
partialRight:function
|
||||
partition:array,object,function
|
||||
percentile:math
|
||||
pick:object,array
|
||||
@ -161,6 +182,8 @@ randomNumberInRange:math,utility,random
|
||||
readFileLines:node,array,string
|
||||
redirect:browser,url
|
||||
reducedFilter:array
|
||||
reduceSuccessive:array,function
|
||||
reduceWhich:array,function
|
||||
remove:array
|
||||
reverseString:string,array
|
||||
RGBToHex:utility
|
||||
@ -181,6 +204,7 @@ size:object,array,string
|
||||
sleep:function,promise
|
||||
sortCharactersInString:string
|
||||
sortedIndex:array,math
|
||||
sortedLastIndex:array,math
|
||||
splitLines:string
|
||||
spreadOver:adapter
|
||||
standardDeviation:math,array
|
||||
@ -188,9 +212,12 @@ sum:math,array
|
||||
sumBy:math,array,function
|
||||
sumPower:math
|
||||
symmetricDifference:array,math
|
||||
symmetricDifferenceBy:array,function
|
||||
symmetricDifferenceWith:array,function
|
||||
tail:array
|
||||
take:array
|
||||
takeRight:array
|
||||
times:function
|
||||
timeTaken:utility
|
||||
toCamelCase:string,regexp
|
||||
toDecimalMark:utility,math
|
||||
@ -203,16 +230,24 @@ toSnakeCase:string,regexp
|
||||
transform:object,array
|
||||
truncateString:string
|
||||
truthCheckCollection:object,logic,array
|
||||
unary:adapter,function
|
||||
unescapeHTML:string,browser
|
||||
unfold:function,array
|
||||
union:array,math
|
||||
unionBy:array,function
|
||||
unionWith:array,function
|
||||
uniqueElements:array
|
||||
untildify:node,string
|
||||
unzip:array
|
||||
unzipWith:array,function,advanced
|
||||
URLJoin:string,utility,regexp
|
||||
UUIDGeneratorBrowser:browser,utility,random
|
||||
UUIDGeneratorNode:node,utility,random
|
||||
validateNumber:utility,math
|
||||
without:array
|
||||
words:string,regexp
|
||||
xProd:array,math
|
||||
yesNo:utility,regexp
|
||||
zip:array
|
||||
zipObject:array,object
|
||||
zipWith:array,advanced
|
||||
|
||||
@ -2,4 +2,4 @@ const JSONToDate = arr => {
|
||||
const dt = new Date(parseInt(arr.toString().substr(6)));
|
||||
return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`;
|
||||
};
|
||||
module.exports = JSONToDate
|
||||
module.exports = JSONToDate
|
||||
@ -2,12 +2,12 @@ const test = require('tape');
|
||||
const JSONToDate = require('./JSONToDate.js');
|
||||
|
||||
test('Testing JSONToDate', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof JSONToDate === 'function', 'JSONToDate is a Function');
|
||||
//t.deepEqual(JSONToDate(args..), 'Expected');
|
||||
//t.equal(JSONToDate(args..), 'Expected');
|
||||
//t.false(JSONToDate(args..), 'Expected');
|
||||
//t.throws(JSONToDate(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof JSONToDate === 'function', 'JSONToDate is a Function');
|
||||
//t.deepEqual(JSONToDate(args..), 'Expected');
|
||||
//t.equal(JSONToDate(args..), 'Expected');
|
||||
//t.false(JSONToDate(args..), 'Expected');
|
||||
//t.throws(JSONToDate(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -1,4 +1,4 @@
|
||||
const fs = require('fs');
|
||||
const JSONToFile = (obj, filename) =>
|
||||
fs.writeFile(`${filename}.json`, JSON.stringify(obj, null, 2));
|
||||
module.exports = JSONToFile
|
||||
module.exports = JSONToFile
|
||||
@ -2,12 +2,12 @@ const test = require('tape');
|
||||
const JSONToFile = require('./JSONToFile.js');
|
||||
|
||||
test('Testing JSONToFile', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof JSONToFile === 'function', 'JSONToFile is a Function');
|
||||
//t.deepEqual(JSONToFile(args..), 'Expected');
|
||||
//t.equal(JSONToFile(args..), 'Expected');
|
||||
//t.false(JSONToFile(args..), 'Expected');
|
||||
//t.throws(JSONToFile(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof JSONToFile === 'function', 'JSONToFile is a Function');
|
||||
//t.deepEqual(JSONToFile(args..), 'Expected');
|
||||
//t.equal(JSONToFile(args..), 'Expected');
|
||||
//t.false(JSONToFile(args..), 'Expected');
|
||||
//t.throws(JSONToFile(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -2,12 +2,12 @@ const test = require('tape');
|
||||
const README = require('./README.js');
|
||||
|
||||
test('Testing README', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof README === 'function', 'README is a Function');
|
||||
//t.deepEqual(README(args..), 'Expected');
|
||||
//t.equal(README(args..), 'Expected');
|
||||
//t.false(README(args..), 'Expected');
|
||||
//t.throws(README(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof README === 'function', 'README is a Function');
|
||||
//t.deepEqual(README(args..), 'Expected');
|
||||
//t.equal(README(args..), 'Expected');
|
||||
//t.false(README(args..), 'Expected');
|
||||
//t.throws(README(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -1,2 +1,2 @@
|
||||
const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');
|
||||
module.exports = RGBToHex
|
||||
module.exports = RGBToHex
|
||||
@ -2,13 +2,13 @@ const test = require('tape');
|
||||
const RGBToHex = require('./RGBToHex.js');
|
||||
|
||||
test('Testing RGBToHex', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof RGBToHex === 'function', 'RGBToHex is a Function');
|
||||
t.equal(RGBToHex(255, 165, 1), 'ffa501', "Converts the values of RGB components to a color code.");
|
||||
//t.deepEqual(RGBToHex(args..), 'Expected');
|
||||
//t.equal(RGBToHex(args..), 'Expected');
|
||||
//t.false(RGBToHex(args..), 'Expected');
|
||||
//t.throws(RGBToHex(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof RGBToHex === 'function', 'RGBToHex is a Function');
|
||||
t.equal(RGBToHex(255, 165, 1), 'ffa501', "Converts the values of RGB components to a color code.");
|
||||
//t.deepEqual(RGBToHex(args..), 'Expected');
|
||||
//t.equal(RGBToHex(args..), 'Expected');
|
||||
//t.false(RGBToHex(args..), 'Expected');
|
||||
//t.throws(RGBToHex(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -7,4 +7,4 @@ args
|
||||
.replace(/\/(\?|&|#[^!])/g, '$1')
|
||||
.replace(/\?/g, '&')
|
||||
.replace('&', '?');
|
||||
module.exports = URLJoin
|
||||
module.exports = URLJoin
|
||||
@ -2,14 +2,14 @@ const test = require('tape');
|
||||
const URLJoin = require('./URLJoin.js');
|
||||
|
||||
test('Testing URLJoin', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof URLJoin === 'function', 'URLJoin is a Function');
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof URLJoin === 'function', 'URLJoin is a Function');
|
||||
t.equal(URLJoin('http://www.google.com', 'a', '/b/cd', '?foo=123', '?bar=foo'), 'http://www.google.com/a/b/cd?foo=123&bar=foo', 'Returns proper URL');
|
||||
t.equal(URLJoin('file://www.google.com', 'a', '/b/cd', '?foo=123', '?bar=foo'), 'file:///www.google.com/a/b/cd?foo=123&bar=foo', 'Returns proper URL');
|
||||
//t.deepEqual(URLJoin(args..), 'Expected');
|
||||
//t.equal(URLJoin(args..), 'Expected');
|
||||
//t.false(URLJoin(args..), 'Expected');
|
||||
//t.throws(URLJoin(args..), 'Expected');
|
||||
t.end();
|
||||
//t.deepEqual(URLJoin(args..), 'Expected');
|
||||
//t.equal(URLJoin(args..), 'Expected');
|
||||
//t.false(URLJoin(args..), 'Expected');
|
||||
//t.throws(URLJoin(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
|
||||
@ -2,4 +2,4 @@ const UUIDGeneratorBrowser = () =>
|
||||
([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
|
||||
(c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
|
||||
);
|
||||
module.exports = UUIDGeneratorBrowser
|
||||
module.exports = UUIDGeneratorBrowser
|
||||
@ -2,12 +2,12 @@ const test = require('tape');
|
||||
const UUIDGeneratorBrowser = require('./UUIDGeneratorBrowser.js');
|
||||
|
||||
test('Testing UUIDGeneratorBrowser', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof UUIDGeneratorBrowser === 'function', 'UUIDGeneratorBrowser is a Function');
|
||||
//t.deepEqual(UUIDGeneratorBrowser(args..), 'Expected');
|
||||
//t.equal(UUIDGeneratorBrowser(args..), 'Expected');
|
||||
//t.false(UUIDGeneratorBrowser(args..), 'Expected');
|
||||
//t.throws(UUIDGeneratorBrowser(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof UUIDGeneratorBrowser === 'function', 'UUIDGeneratorBrowser is a Function');
|
||||
//t.deepEqual(UUIDGeneratorBrowser(args..), 'Expected');
|
||||
//t.equal(UUIDGeneratorBrowser(args..), 'Expected');
|
||||
//t.false(UUIDGeneratorBrowser(args..), 'Expected');
|
||||
//t.throws(UUIDGeneratorBrowser(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -3,4 +3,4 @@ const UUIDGeneratorNode = () =>
|
||||
([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
|
||||
(c ^ (crypto.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16)
|
||||
);
|
||||
module.exports = UUIDGeneratorNode
|
||||
module.exports = UUIDGeneratorNode
|
||||
@ -2,12 +2,12 @@ const test = require('tape');
|
||||
const UUIDGeneratorNode = require('./UUIDGeneratorNode.js');
|
||||
|
||||
test('Testing UUIDGeneratorNode', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof UUIDGeneratorNode === 'function', 'UUIDGeneratorNode is a Function');
|
||||
//t.deepEqual(UUIDGeneratorNode(args..), 'Expected');
|
||||
//t.equal(UUIDGeneratorNode(args..), 'Expected');
|
||||
//t.false(UUIDGeneratorNode(args..), 'Expected');
|
||||
//t.throws(UUIDGeneratorNode(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof UUIDGeneratorNode === 'function', 'UUIDGeneratorNode is a Function');
|
||||
//t.deepEqual(UUIDGeneratorNode(args..), 'Expected');
|
||||
//t.equal(UUIDGeneratorNode(args..), 'Expected');
|
||||
//t.false(UUIDGeneratorNode(args..), 'Expected');
|
||||
//t.throws(UUIDGeneratorNode(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -8,4 +8,4 @@ acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)
|
||||
[]
|
||||
);
|
||||
};
|
||||
module.exports = anagrams
|
||||
module.exports = anagrams
|
||||
@ -2,13 +2,13 @@ const test = require('tape');
|
||||
const anagrams = require('./anagrams.js');
|
||||
|
||||
test('Testing anagrams', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof anagrams === 'function', 'anagrams is a Function');
|
||||
t.deepEqual(anagrams('abc'), ['abc','acb','bac','bca','cab','cba'], "Generates all anagrams of a string");
|
||||
//t.deepEqual(anagrams(args..), 'Expected');
|
||||
//t.equal(anagrams(args..), 'Expected');
|
||||
//t.false(anagrams(args..), 'Expected');
|
||||
//t.throws(anagrams(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof anagrams === 'function', 'anagrams is a Function');
|
||||
t.deepEqual(anagrams('abc'), ['abc','acb','bac','bca','cab','cba'], "Generates all anagrams of a string");
|
||||
//t.deepEqual(anagrams(args..), 'Expected');
|
||||
//t.equal(anagrams(args..), 'Expected');
|
||||
//t.false(anagrams(args..), 'Expected');
|
||||
//t.throws(anagrams(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -1,3 +1,3 @@
|
||||
const arrayToHtmlList = (arr, listID) =>
|
||||
arr.map(item => (document.querySelector('#' + listID).innerHTML += `<li>${item}</li>`));
|
||||
module.exports = arrayToHtmlList
|
||||
module.exports = arrayToHtmlList
|
||||
@ -2,12 +2,12 @@ const test = require('tape');
|
||||
const arrayToHtmlList = require('./arrayToHtmlList.js');
|
||||
|
||||
test('Testing arrayToHtmlList', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof arrayToHtmlList === 'function', 'arrayToHtmlList is a Function');
|
||||
//t.deepEqual(arrayToHtmlList(args..), 'Expected');
|
||||
//t.equal(arrayToHtmlList(args..), 'Expected');
|
||||
//t.false(arrayToHtmlList(args..), 'Expected');
|
||||
//t.throws(arrayToHtmlList(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof arrayToHtmlList === 'function', 'arrayToHtmlList is a Function');
|
||||
//t.deepEqual(arrayToHtmlList(args..), 'Expected');
|
||||
//t.equal(arrayToHtmlList(args..), 'Expected');
|
||||
//t.false(arrayToHtmlList(args..), 'Expected');
|
||||
//t.throws(arrayToHtmlList(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
2
test/ary/ary.js
Normal file
2
test/ary/ary.js
Normal file
@ -0,0 +1,2 @@
|
||||
const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
|
||||
module.exports = ary
|
||||
13
test/ary/ary.test.js
Normal file
13
test/ary/ary.test.js
Normal file
@ -0,0 +1,13 @@
|
||||
const test = require('tape');
|
||||
const ary = require('./ary.js');
|
||||
|
||||
test('Testing ary', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof ary === 'function', 'ary is a Function');
|
||||
//t.deepEqual(ary(args..), 'Expected');
|
||||
//t.equal(ary(args..), 'Expected');
|
||||
//t.false(ary(args..), 'Expected');
|
||||
//t.throws(ary(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -1,2 +1,2 @@
|
||||
const atob = str => new Buffer(str, 'base64').toString('binary');
|
||||
module.exports = atob
|
||||
module.exports = atob
|
||||
@ -2,12 +2,14 @@ const test = require('tape');
|
||||
const atob = require('./atob.js');
|
||||
|
||||
test('Testing atob', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof atob === 'function', 'atob is a Function');
|
||||
//t.deepEqual(atob(args..), 'Expected');
|
||||
//t.equal(atob(args..), 'Expected');
|
||||
//t.false(atob(args..), 'Expected');
|
||||
//t.throws(atob(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof atob === 'function', 'atob is a Function');
|
||||
t.equals(atob('Zm9vYmFy'), 'foobar', 'atob("Zm9vYmFy") equals "foobar"');
|
||||
t.equals(atob('Z'), '', 'atob("Z") returns ""');
|
||||
//t.deepEqual(atob(args..), 'Expected');
|
||||
//t.equal(atob(args..), 'Expected');
|
||||
//t.false(atob(args..), 'Expected');
|
||||
//t.throws(atob(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
const average = (...nums) => [...nums].reduce((acc, val) => acc + val, 0) / nums.length;
|
||||
module.exports = average
|
||||
module.exports = average
|
||||
@ -2,23 +2,23 @@ const test = require('tape');
|
||||
const average = require('./average.js');
|
||||
|
||||
test('Testing average', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof average === 'function', 'average is a Function');
|
||||
t.true(average(true) === 1, 'average(true) returns 0');
|
||||
t.true(average(false) === 0, 'average(false) returns 1');
|
||||
t.equal(average(9, 1), 5, 'average(9, 1) returns 5');
|
||||
t.equal(average(153, 44, 55, 64, 71, 1122, 322774, 2232, 23423, 234, 3631), 32163.909090909092, 'average(153, 44, 55, 64, 71, 1122, 322774, 2232, 23423, 234, 3631) returns 32163.909090909092 ');
|
||||
t.equal(average(1, 2, 3), 2, 'average(1, 2, 3) returns 2');
|
||||
t.equal(average(153, 44, 55, 64, 71, 1122, 322774, 2232, 23423, 234, 3631), 32163.909090909092, 'average(153, 44, 55, 64, 71, 1122, 322774, 2232, 23423, 234, 3631) returns 32163.909090909092 ');
|
||||
t.equal(average(1, 2, 3), 2, 'average(1, 2, 3) returns 2');
|
||||
t.equal(average(null), 0, 'average(null) returns 0');
|
||||
t.true(isNaN(average(undefined)), 'average(1, 2, 3) returns NaN');
|
||||
t.true(isNaN(average('String')), 'average(String) returns NaN');
|
||||
t.true(isNaN(average({ a: 123})), 'average({ a: 123}) returns NaN');
|
||||
t.true(isNaN(average([undefined, 0, 'string'])), 'average([undefined, 0, string]) returns NaN');
|
||||
t.true(isNaN(average(undefined)), 'average(1, 2, 3) returns NaN');
|
||||
t.true(isNaN(average('String')), 'average(String) returns NaN');
|
||||
t.true(isNaN(average({ a: 123})), 'average({ a: 123}) returns NaN');
|
||||
t.true(isNaN(average([undefined, 0, 'string'])), 'average([undefined, 0, string]) returns NaN');
|
||||
|
||||
let start = new Date().getTime();
|
||||
average(153, 44, 55, 64, 71, 1122, 322774, 2232, 23423, 234, 3631);
|
||||
let end = new Date().getTime();
|
||||
t.true((end - start) < 2000, 'head([1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 1122, 32124, 23232]) takes less than 2s to run');
|
||||
t.end();
|
||||
t.end();
|
||||
});
|
||||
@ -1,4 +1,4 @@
|
||||
const averageBy = (arr, fn) =>
|
||||
arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => acc + val, 0) /
|
||||
arr.length;
|
||||
module.exports = averageBy
|
||||
module.exports = averageBy
|
||||
@ -2,12 +2,14 @@ const test = require('tape');
|
||||
const averageBy = require('./averageBy.js');
|
||||
|
||||
test('Testing averageBy', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof averageBy === 'function', 'averageBy is a Function');
|
||||
//t.deepEqual(averageBy(args..), 'Expected');
|
||||
//t.equal(averageBy(args..), 'Expected');
|
||||
//t.false(averageBy(args..), 'Expected');
|
||||
//t.throws(averageBy(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof averageBy === 'function', 'averageBy is a Function');
|
||||
t.equals(averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n), 5, 'Produces the right result with a function');
|
||||
t.equals(averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'), 5, 'Produces the right result with a property name');
|
||||
//t.deepEqual(averageBy(args..), 'Expected');
|
||||
//t.equal(averageBy(args..), 'Expected');
|
||||
//t.false(averageBy(args..), 'Expected');
|
||||
//t.throws(averageBy(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
|
||||
@ -5,4 +5,4 @@ if (arr[mid] > val) return binarySearch(arr, val, start, mid - 1);
|
||||
if (arr[mid] < val) return binarySearch(arr, val, mid + 1, end);
|
||||
return mid;
|
||||
}
|
||||
module.exports = binarySearch
|
||||
module.exports = binarySearch
|
||||
@ -2,12 +2,12 @@ const test = require('tape');
|
||||
const binarySearch = require('./binarySearch.js');
|
||||
|
||||
test('Testing binarySearch', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof binarySearch === 'function', 'binarySearch is a Function');
|
||||
//t.deepEqual(binarySearch(args..), 'Expected');
|
||||
//t.equal(binarySearch(args..), 'Expected');
|
||||
//t.false(binarySearch(args..), 'Expected');
|
||||
//t.throws(binarySearch(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof binarySearch === 'function', 'binarySearch is a Function');
|
||||
//t.deepEqual(binarySearch(args..), 'Expected');
|
||||
//t.equal(binarySearch(args..), 'Expected');
|
||||
//t.false(binarySearch(args..), 'Expected');
|
||||
//t.throws(binarySearch(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
5
test/bind/bind.js
Normal file
5
test/bind/bind.js
Normal file
@ -0,0 +1,5 @@
|
||||
const bind = (fn, context, ...args) =>
|
||||
function() {
|
||||
return fn.apply(context, args.concat(...arguments));
|
||||
};
|
||||
module.exports = bind
|
||||
13
test/bind/bind.test.js
Normal file
13
test/bind/bind.test.js
Normal file
@ -0,0 +1,13 @@
|
||||
const test = require('tape');
|
||||
const bind = require('./bind.js');
|
||||
|
||||
test('Testing bind', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof bind === 'function', 'bind is a Function');
|
||||
//t.deepEqual(bind(args..), 'Expected');
|
||||
//t.equal(bind(args..), 'Expected');
|
||||
//t.false(bind(args..), 'Expected');
|
||||
//t.throws(bind(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
5
test/bindKey/bindKey.js
Normal file
5
test/bindKey/bindKey.js
Normal file
@ -0,0 +1,5 @@
|
||||
const bindKey = (context, fn, ...args) =>
|
||||
function() {
|
||||
return context[fn].apply(context, args.concat(...arguments));
|
||||
};
|
||||
module.exports = bindKey
|
||||
13
test/bindKey/bindKey.test.js
Normal file
13
test/bindKey/bindKey.test.js
Normal file
@ -0,0 +1,13 @@
|
||||
const test = require('tape');
|
||||
const bindKey = require('./bindKey.js');
|
||||
|
||||
test('Testing bindKey', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof bindKey === 'function', 'bindKey is a Function');
|
||||
//t.deepEqual(bindKey(args..), 'Expected');
|
||||
//t.equal(bindKey(args..), 'Expected');
|
||||
//t.false(bindKey(args..), 'Expected');
|
||||
//t.throws(bindKey(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -1,4 +1,4 @@
|
||||
const bottomVisible = () =>
|
||||
document.documentElement.clientHeight + window.scrollY >=
|
||||
(document.documentElement.scrollHeight || document.documentElement.clientHeight);
|
||||
module.exports = bottomVisible
|
||||
module.exports = bottomVisible
|
||||
@ -2,12 +2,12 @@ const test = require('tape');
|
||||
const bottomVisible = require('./bottomVisible.js');
|
||||
|
||||
test('Testing bottomVisible', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof bottomVisible === 'function', 'bottomVisible is a Function');
|
||||
//t.deepEqual(bottomVisible(args..), 'Expected');
|
||||
//t.equal(bottomVisible(args..), 'Expected');
|
||||
//t.false(bottomVisible(args..), 'Expected');
|
||||
//t.throws(bottomVisible(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof bottomVisible === 'function', 'bottomVisible is a Function');
|
||||
//t.deepEqual(bottomVisible(args..), 'Expected');
|
||||
//t.equal(bottomVisible(args..), 'Expected');
|
||||
//t.false(bottomVisible(args..), 'Expected');
|
||||
//t.throws(bottomVisible(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -1,2 +1,2 @@
|
||||
const btoa = str => new Buffer(str, 'binary').toString('base64');
|
||||
module.exports = btoa
|
||||
module.exports = btoa
|
||||
@ -2,12 +2,13 @@ const test = require('tape');
|
||||
const btoa = require('./btoa.js');
|
||||
|
||||
test('Testing btoa', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof btoa === 'function', 'btoa is a Function');
|
||||
//t.deepEqual(btoa(args..), 'Expected');
|
||||
//t.equal(btoa(args..), 'Expected');
|
||||
//t.false(btoa(args..), 'Expected');
|
||||
//t.throws(btoa(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof btoa === 'function', 'btoa is a Function');
|
||||
t.equals(btoa('foobar'), 'Zm9vYmFy', 'btoa("foobar") equals "Zm9vYmFy"');
|
||||
//t.deepEqual(btoa(args..), 'Expected');
|
||||
//t.equal(btoa(args..), 'Expected');
|
||||
//t.false(btoa(args..), 'Expected');
|
||||
//t.throws(btoa(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
const byteSize = str => new Blob([str]).size;
|
||||
module.exports = byteSize
|
||||
module.exports = byteSize
|
||||
@ -2,14 +2,14 @@ const test = require('tape');
|
||||
const byteSize = require('./byteSize.js');
|
||||
|
||||
test('Testing byteSize', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof byteSize === 'function', 'byteSize is a Function');
|
||||
// Works only in browser
|
||||
// t.equal(byteSize('Hello World'), 11, "Returns the length of a string in bytes");
|
||||
//t.deepEqual(byteSize(args..), 'Expected');
|
||||
//t.equal(byteSize(args..), 'Expected');
|
||||
//t.false(byteSize(args..), 'Expected');
|
||||
//t.throws(byteSize(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof byteSize === 'function', 'byteSize is a Function');
|
||||
// Works only in browser
|
||||
// t.equal(byteSize('Hello World'), 11, "Returns the length of a string in bytes");
|
||||
//t.deepEqual(byteSize(args..), 'Expected');
|
||||
//t.equal(byteSize(args..), 'Expected');
|
||||
//t.false(byteSize(args..), 'Expected');
|
||||
//t.throws(byteSize(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -1,2 +1,2 @@
|
||||
const call = (key, ...args) => context => context[key](...args);
|
||||
module.exports = call
|
||||
module.exports = call
|
||||
@ -2,12 +2,12 @@ const test = require('tape');
|
||||
const call = require('./call.js');
|
||||
|
||||
test('Testing call', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof call === 'function', 'call is a Function');
|
||||
//t.deepEqual(call(args..), 'Expected');
|
||||
//t.equal(call(args..), 'Expected');
|
||||
//t.false(call(args..), 'Expected');
|
||||
//t.throws(call(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof call === 'function', 'call is a Function');
|
||||
//t.deepEqual(call(args..), 'Expected');
|
||||
//t.equal(call(args..), 'Expected');
|
||||
//t.false(call(args..), 'Expected');
|
||||
//t.throws(call(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -1,3 +1,3 @@
|
||||
const capitalize = ([first, ...rest], lowerRest = false) =>
|
||||
first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join(''));
|
||||
module.exports = capitalize
|
||||
module.exports = capitalize
|
||||
@ -2,14 +2,14 @@ const test = require('tape');
|
||||
const capitalize = require('./capitalize.js');
|
||||
|
||||
test('Testing capitalize', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof capitalize === 'function', 'capitalize is a Function');
|
||||
t.equal(capitalize('fooBar'), 'FooBar', "Capitalizes the first letter of a string");
|
||||
t.equal(capitalize('fooBar', true), 'Foobar', "Capitalizes the first letter of a string");
|
||||
//t.deepEqual(capitalize(args..), 'Expected');
|
||||
//t.equal(capitalize(args..), 'Expected');
|
||||
//t.false(capitalize(args..), 'Expected');
|
||||
//t.throws(capitalize(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof capitalize === 'function', 'capitalize is a Function');
|
||||
t.equal(capitalize('fooBar'), 'FooBar', "Capitalizes the first letter of a string");
|
||||
t.equal(capitalize('fooBar', true), 'Foobar', "Capitalizes the first letter of a string");
|
||||
//t.deepEqual(capitalize(args..), 'Expected');
|
||||
//t.equal(capitalize(args..), 'Expected');
|
||||
//t.false(capitalize(args..), 'Expected');
|
||||
//t.throws(capitalize(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -1,2 +1,2 @@
|
||||
const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase());
|
||||
module.exports = capitalizeEveryWord
|
||||
module.exports = capitalizeEveryWord
|
||||
@ -2,13 +2,13 @@ const test = require('tape');
|
||||
const capitalizeEveryWord = require('./capitalizeEveryWord.js');
|
||||
|
||||
test('Testing capitalizeEveryWord', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof capitalizeEveryWord === 'function', 'capitalizeEveryWord is a Function');
|
||||
t.equal(capitalizeEveryWord('hello world!'), 'Hello World!', "Capitalizes the first letter of every word in a string");
|
||||
//t.deepEqual(capitalizeEveryWord(args..), 'Expected');
|
||||
//t.equal(capitalizeEveryWord(args..), 'Expected');
|
||||
//t.false(capitalizeEveryWord(args..), 'Expected');
|
||||
//t.throws(capitalizeEveryWord(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof capitalizeEveryWord === 'function', 'capitalizeEveryWord is a Function');
|
||||
t.equal(capitalizeEveryWord('hello world!'), 'Hello World!', "Capitalizes the first letter of every word in a string");
|
||||
//t.deepEqual(capitalizeEveryWord(args..), 'Expected');
|
||||
//t.equal(capitalizeEveryWord(args..), 'Expected');
|
||||
//t.false(capitalizeEveryWord(args..), 'Expected');
|
||||
//t.throws(capitalizeEveryWord(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
2
test/castArray/castArray.js
Normal file
2
test/castArray/castArray.js
Normal file
@ -0,0 +1,2 @@
|
||||
const castArray = val => (Array.isArray(val) ? val : [val]);
|
||||
module.exports = castArray
|
||||
18
test/castArray/castArray.test.js
Normal file
18
test/castArray/castArray.test.js
Normal file
@ -0,0 +1,18 @@
|
||||
const test = require('tape');
|
||||
const castArray = require('./castArray.js');
|
||||
|
||||
test('Testing castArray', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof castArray === 'function', 'castArray is a Function');
|
||||
t.deepEqual(castArray(1), [1], 'Works for single values');
|
||||
t.deepEqual(castArray([1]), [1], 'Works for arrays with one value');
|
||||
t.deepEqual(castArray([1,2,3]), [1,2,3], 'Works for arrays with multiple value');
|
||||
t.deepEqual(castArray('test'), ['test'], 'Works for strings');
|
||||
t.deepEqual(castArray({}), [{}], 'Works for objects');
|
||||
//t.deepEqual(castArray(args..), 'Expected');
|
||||
//t.equal(castArray(args..), 'Expected');
|
||||
//t.false(castArray(args..), 'Expected');
|
||||
//t.throws(castArray(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -3,4 +3,4 @@ let curr = 0;
|
||||
const next = () => fns[curr++](next);
|
||||
next();
|
||||
};
|
||||
module.exports = chainAsync
|
||||
module.exports = chainAsync
|
||||
@ -2,12 +2,12 @@ const test = require('tape');
|
||||
const chainAsync = require('./chainAsync.js');
|
||||
|
||||
test('Testing chainAsync', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof chainAsync === 'function', 'chainAsync is a Function');
|
||||
//t.deepEqual(chainAsync(args..), 'Expected');
|
||||
//t.equal(chainAsync(args..), 'Expected');
|
||||
//t.false(chainAsync(args..), 'Expected');
|
||||
//t.throws(chainAsync(args..), 'Expected');
|
||||
t.end();
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof chainAsync === 'function', 'chainAsync is a Function');
|
||||
//t.deepEqual(chainAsync(args..), 'Expected');
|
||||
//t.equal(chainAsync(args..), 'Expected');
|
||||
//t.false(chainAsync(args..), 'Expected');
|
||||
//t.throws(chainAsync(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -2,4 +2,4 @@ const chunk = (arr, size) =>
|
||||
Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
|
||||
arr.slice(i * size, i * size + size)
|
||||
);
|
||||
module.exports = chunk
|
||||
module.exports = chunk
|
||||
@ -2,11 +2,11 @@ const test = require('tape');
|
||||
const chunk = require('./chunk.js');
|
||||
|
||||
test('Testing chunk', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof chunk === 'function', 'chunk is a Function');
|
||||
t.deepEqual(chunk([1, 2, 3, 4, 5], 2), [[1,2],[3,4],[5]], "chunk([1, 2, 3, 4, 5], 2) returns [[1,2],[3,4],[5]] ");
|
||||
t.deepEqual(chunk([]), [], 'chunk([]) returns []');
|
||||
t.deepEqual(chunk([1, 2, 3, 4, 5], 2), [[1,2],[3,4],[5]], "chunk([1, 2, 3, 4, 5], 2) returns [[1,2],[3,4],[5]] ");
|
||||
t.deepEqual(chunk([]), [], 'chunk([]) returns []');
|
||||
t.deepEqual(chunk(123), [], 'chunk(123) returns []');
|
||||
t.deepEqual(chunk({ a: 123}), [], 'chunk({ a: 123}) returns []');
|
||||
t.deepEqual(chunk('string', 2), [ 'st', 'ri', 'ng' ], 'chunk(string, 2) returns [ st, ri, ng ]');
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user