Merge branch 'master' into browser-tests

This commit is contained in:
Angelos Chalaris
2018-01-26 11:22:30 +02:00
committed by GitHub
598 changed files with 6282 additions and 2559 deletions

1030
README.md

File diff suppressed because it is too large Load Diff

548
dist/_30s.es5.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

208
dist/_30s.esm.js vendored
View File

@ -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(
/&amp;|&lt;|&gt;|&#39;|&quot;/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
View File

@ -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(
/&amp;|&lt;|&gt;|&#39;|&quot;/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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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`

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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'
```

View File

@ -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
View 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
View 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'
```

View 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]
```

View 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]
```

View File

@ -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
View 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
View 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
View 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
View 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
```

View File

@ -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
View 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
```

View File

@ -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
View 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
View 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
View 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!'
```

View 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
View 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}
```

View 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
```

View 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 ]
```

View 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
View 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
```

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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']
```

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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();
});

View File

@ -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

View File

@ -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();
});

View File

@ -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();
});

View File

@ -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

View File

@ -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();
});

View File

@ -7,4 +7,4 @@ args
.replace(/\/(\?|&|#[^!])/g, '$1')
.replace(/\?/g, '&')
.replace('&', '?');
module.exports = URLJoin
module.exports = URLJoin

View File

@ -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();
});

View File

@ -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

View File

@ -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();
});

View File

@ -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

View File

@ -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();
});

View File

@ -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

View File

@ -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();
});

View File

@ -1,3 +1,3 @@
const arrayToHtmlList = (arr, listID) =>
arr.map(item => (document.querySelector('#' + listID).innerHTML += `<li>${item}</li>`));
module.exports = arrayToHtmlList
module.exports = arrayToHtmlList

View File

@ -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
View 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
View 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();
});

View File

@ -1,2 +1,2 @@
const atob = str => new Buffer(str, 'base64').toString('binary');
module.exports = atob
module.exports = atob

View File

@ -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();
});

View File

@ -1,2 +1,2 @@
const average = (...nums) => [...nums].reduce((acc, val) => acc + val, 0) / nums.length;
module.exports = average
module.exports = average

View File

@ -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();
});

View File

@ -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

View File

@ -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();
});

View File

@ -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

View File

@ -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
View 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
View 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
View File

@ -0,0 +1,5 @@
const bindKey = (context, fn, ...args) =>
function() {
return context[fn].apply(context, args.concat(...arguments));
};
module.exports = bindKey

View 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();
});

View File

@ -1,4 +1,4 @@
const bottomVisible = () =>
document.documentElement.clientHeight + window.scrollY >=
(document.documentElement.scrollHeight || document.documentElement.clientHeight);
module.exports = bottomVisible
module.exports = bottomVisible

View File

@ -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();
});

View File

@ -1,2 +1,2 @@
const btoa = str => new Buffer(str, 'binary').toString('base64');
module.exports = btoa
module.exports = btoa

View File

@ -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();
});

View File

@ -1,2 +1,2 @@
const byteSize = str => new Blob([str]).size;
module.exports = byteSize
module.exports = byteSize

View File

@ -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();
});

View File

@ -1,2 +1,2 @@
const call = (key, ...args) => context => context[key](...args);
module.exports = call
module.exports = call

View File

@ -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();
});

View File

@ -1,3 +1,3 @@
const capitalize = ([first, ...rest], lowerRest = false) =>
first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join(''));
module.exports = capitalize
module.exports = capitalize

View File

@ -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();
});

View File

@ -1,2 +1,2 @@
const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase());
module.exports = capitalizeEveryWord
module.exports = capitalizeEveryWord

View File

@ -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();
});

View File

@ -0,0 +1,2 @@
const castArray = val => (Array.isArray(val) ? val : [val]);
module.exports = castArray

View 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();
});

View File

@ -3,4 +3,4 @@ let curr = 0;
const next = () => fns[curr++](next);
next();
};
module.exports = chainAsync
module.exports = chainAsync

View File

@ -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();
});

View File

@ -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

View File

@ -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