Merge branch 'master' into lev-dist
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@ -4,3 +4,7 @@ currentSnippet\.js
|
||||
.idea
|
||||
test.sh
|
||||
/*.log
|
||||
|
||||
dist/flavor\.min\.css
|
||||
|
||||
dist/flavor\.css
|
||||
|
||||
228
README.md
228
README.md
@ -141,6 +141,7 @@ average(1, 2, 3);
|
||||
* [`none`](#none)
|
||||
* [`nthElement`](#nthelement)
|
||||
* [`partition`](#partition)
|
||||
* [`permutations`](#permutations)
|
||||
* [`pull`](#pull)
|
||||
* [`pullAtIndex`](#pullatindex)
|
||||
* [`pullAtValue`](#pullatvalue)
|
||||
@ -343,6 +344,7 @@ average(1, 2, 3);
|
||||
* [`matches`](#matches)
|
||||
* [`matchesWith`](#matcheswith)
|
||||
* [`merge`](#merge)
|
||||
* [`nest`](#nest)
|
||||
* [`objectFromPairs`](#objectfrompairs)
|
||||
* [`objectToPairs`](#objecttopairs)
|
||||
* [`omit`](#omit)
|
||||
@ -363,7 +365,6 @@ average(1, 2, 3);
|
||||
<details>
|
||||
<summary>View contents</summary>
|
||||
|
||||
* [`anagrams`](#anagrams)
|
||||
* [`byteSize`](#bytesize)
|
||||
* [`capitalize`](#capitalize)
|
||||
* [`capitalizeEveryWord`](#capitalizeeveryword)
|
||||
@ -372,15 +373,18 @@ average(1, 2, 3);
|
||||
* [`escapeRegExp`](#escaperegexp)
|
||||
* [`fromCamelCase`](#fromcamelcase)
|
||||
* [`isAbsoluteURL`](#isabsoluteurl)
|
||||
* [`isAnagram`](#isanagram)
|
||||
* [`isLowerCase`](#islowercase)
|
||||
* [`isUpperCase`](#isuppercase)
|
||||
* [`mask`](#mask)
|
||||
* [`pad`](#pad)
|
||||
* [`palindrome`](#palindrome)
|
||||
* [`pluralize`](#pluralize)
|
||||
* [`removeNonASCII`](#removenonascii)
|
||||
* [`reverseString`](#reversestring)
|
||||
* [`sortCharactersInString`](#sortcharactersinstring)
|
||||
* [`splitLines`](#splitlines)
|
||||
* [`stringPermutations`](#stringpermutations)
|
||||
* [`stripHTMLTags`](#striphtmltags)
|
||||
* [`toCamelCase`](#tocamelcase)
|
||||
* [`toKebabCase`](#tokebabcase)
|
||||
@ -1851,6 +1855,42 @@ partition(users, o => o.active); // [[{ 'user': 'fred', 'age': 40, 'active':
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### permutations
|
||||
|
||||
⚠️ **WARNING**: This function's execution time increases exponentially with each array element. Anything more than 8 to 10 entries will cause your browser to hang as it tries to solve all the different combinations.
|
||||
|
||||
Generates all permutations of an array's elements (contains duplicates).
|
||||
|
||||
Use recursion.
|
||||
For each element in the given array, create all the partial permutations for the rest of its elements.
|
||||
Use `Array.map()` to combine the element with each partial permutation, then `Array.reduce()` to combine all permutations in one array.
|
||||
Base cases are for array `length` equal to `2` or `1`.
|
||||
|
||||
```js
|
||||
const permutations = arr => {
|
||||
if (arr.length <= 2) return arr.length === 2 ? [arr, [arr[1], arr[0]]] : arr;
|
||||
return arr.reduce(
|
||||
(acc, item, i) =>
|
||||
acc.concat(
|
||||
permutations([...arr.slice(0, i), ...arr.slice(i + 1)]).map(val => [item, ...val])
|
||||
),
|
||||
[]
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Examples</summary>
|
||||
|
||||
```js
|
||||
permutations([1, 33, 5]); // [ [ 1, 33, 5 ], [ 1, 5, 33 ], [ 33, 1, 5 ], [ 33, 5, 1 ], [ 5, 1, 33 ], [ 5, 33, 1 ] ]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### pull
|
||||
|
||||
Mutates the original array to filter out the values specified.
|
||||
@ -2272,16 +2312,12 @@ sortedIndexBy([{ x: 4 }, { x: 5 }], { x: 4 }, o => o.x); // 0
|
||||
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.reverse()` and `Array.findIndex()` to find the appropriate last index where the element should be inserted.
|
||||
|
||||
```js
|
||||
const sortedLastIndex = (arr, n) => {
|
||||
const isDescending = arr[0] > arr[arr.length - 1];
|
||||
const index = arr
|
||||
.map((val, i) => [i, val])
|
||||
.reverse()
|
||||
.findIndex(el => (isDescending ? n <= el[1] : n >= el[1]));
|
||||
const index = arr.reverse().findIndex(el => (isDescending ? n <= el : n >= el));
|
||||
return index === -1 ? 0 : arr.length - index - 1;
|
||||
};
|
||||
```
|
||||
@ -2303,16 +2339,17 @@ sortedLastIndex([10, 20, 30, 30, 40], 30); // 3
|
||||
Returns the highest index at which value should be inserted into array in order to maintain its sort order, based on a provided iterator function.
|
||||
|
||||
Check if the array is sorted in descending order (loosely).
|
||||
Use `Array.reverse()` and `Array.findIndex()` to find the appropriate last index where the element should be inserted, based on the iterator function `fn`..
|
||||
Use `Array.map()` to apply the iterator function to all elements of the array.
|
||||
Use `Array.reverse()` and `Array.findIndex()` to find the appropriate last index where the element should be inserted, based on the provided iterator function.
|
||||
|
||||
```js
|
||||
const sortedLastIndexBy = (arr, n, fn) => {
|
||||
const isDescending = fn(arr[0]) > fn(arr[arr.length - 1]);
|
||||
const val = fn(n);
|
||||
const index = arr
|
||||
.map((val, i) => [i, fn(val)])
|
||||
.map(fn)
|
||||
.reverse()
|
||||
.findIndex(el => (isDescending ? val <= el[1] : val >= el[1]));
|
||||
.findIndex(el => (isDescending ? val <= el : val >= el));
|
||||
return index === -1 ? 0 : arr.length - index;
|
||||
};
|
||||
```
|
||||
@ -3722,12 +3759,13 @@ Results in a string representation of tomorrow's date.
|
||||
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 = () => {
|
||||
const tomorrow = (long = false) => {
|
||||
let t = new Date();
|
||||
t.setDate(t.getDate() + 1);
|
||||
return `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, '0')}-${String(
|
||||
const ret = `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, '0')}-${String(
|
||||
t.getDate()
|
||||
).padStart(2, '0')}`;
|
||||
return !long ? ret : `${ret}T00:00:00`;
|
||||
};
|
||||
```
|
||||
|
||||
@ -3736,6 +3774,7 @@ const tomorrow = () => {
|
||||
|
||||
```js
|
||||
tomorrow(); // 2017-12-27 (if current date is 2017-12-26)
|
||||
tomorrow(true); // 2017-12-27T00:00:00 (if current date is 2017-12-26)
|
||||
```
|
||||
|
||||
</details>
|
||||
@ -6221,6 +6260,44 @@ merge(object, other); // { a: [ { x: 2 }, { y: 4 }, { z: 3 } ], b: [ 1, 2, 3 ],
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### nest
|
||||
|
||||
Given a flat array of objects linked to one another, it will nest them recursively.
|
||||
Useful for nesting comments, such as the ones on reddit.com.
|
||||
|
||||
Use recursion.
|
||||
Use `Array.filter()` to filter the items where the `id` matches the `link`, then `Array.map()` to map each one to a new object that has a `children` property which recursively nests the items based on which ones are children of the current item.
|
||||
Omit the second argument, `id`, to default to `null` which indicates the object is not linked to another one (i.e. it is a top level object).
|
||||
Omit the third argument, `link`, to use `'parent_id'` as the default property which links the object to another one by its `id`.
|
||||
|
||||
```js
|
||||
const nest = (items, id = null, link = 'parent_id') =>
|
||||
items
|
||||
.filter(item => item[link] === id)
|
||||
.map(item => ({ ...item, children: nest(items, item.id) }));
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Examples</summary>
|
||||
|
||||
```js
|
||||
// One top level comment
|
||||
const comments = [
|
||||
{ id: 1, parent_id: null },
|
||||
{ id: 2, parent_id: 1 },
|
||||
{ id: 3, parent_id: 1 },
|
||||
{ id: 4, parent_id: 2 },
|
||||
{ id: 5, parent_id: 4 }
|
||||
];
|
||||
const nestedComments = nest(comments); // [{ id: 1, parent_id: null, children: [...] }]
|
||||
```
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### objectFromPairs
|
||||
|
||||
Creates an object from the given key-value pairs.
|
||||
@ -6549,42 +6626,6 @@ unflattenObject({ 'a.b.c': 1, d: 1 }); // { a: { b: { c: 1 } }, d: 1 }
|
||||
---
|
||||
## 📜 String
|
||||
|
||||
### anagrams
|
||||
|
||||
⚠️ **WARNING**: This function's execution time increases exponentially with each character. Anything more than 8 to 10 characters will cause your browser to hang as it tries to solve all the different combinations.
|
||||
|
||||
Generates all anagrams of a string (contains duplicates).
|
||||
|
||||
Use recursion.
|
||||
For each letter in the given string, create all the partial anagrams for the rest of its letters.
|
||||
Use `Array.map()` to combine the letter with each partial anagram, then `Array.reduce()` to combine all anagrams in one array.
|
||||
Base cases are for string `length` equal to `2` or `1`.
|
||||
|
||||
```js
|
||||
const anagrams = str => {
|
||||
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
|
||||
return str
|
||||
.split('')
|
||||
.reduce(
|
||||
(acc, letter, i) =>
|
||||
acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)),
|
||||
[]
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Examples</summary>
|
||||
|
||||
```js
|
||||
anagrams('abc'); // ['abc','acb','bac','bca','cab','cba']
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### byteSize
|
||||
|
||||
Returns the length of a string in bytes.
|
||||
@ -6788,6 +6829,37 @@ isAbsoluteURL('/foo/bar'); // false
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### isAnagram
|
||||
|
||||
Checks if a string is an anagram of another string (case-insensitive, ignores spaces, punctuation and special characters).
|
||||
|
||||
Use `String.toLowerCase()`, `String.replace()` with an appropriate regular expression to remove unnecessary characters, `String.split('')`, `Array.sort()` and `Array.join('')` on both strings to normalize them, then check if their normalized forms are equal.
|
||||
|
||||
```js
|
||||
const isAnagram = (str1, str2) => {
|
||||
const normalize = str =>
|
||||
str
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]/gi, '')
|
||||
.split('')
|
||||
.sort()
|
||||
.join('');
|
||||
return normalize(str1) === normalize(str2);
|
||||
};
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Examples</summary>
|
||||
|
||||
```js
|
||||
isAnagram('iceman', 'cinema'); // true
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### isLowerCase
|
||||
|
||||
Checks if a string is lower case.
|
||||
@ -6865,6 +6937,32 @@ mask(1234567890, -4, '$'); // '$$$$567890'
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### pad
|
||||
|
||||
Pads a string on both sides with the specified character, if it's shorter than the specified length.
|
||||
|
||||
Use `String.padStart()` and `String.padEnd()` to pad both sides of the given string.
|
||||
Omit the third argument, `char`, to use the whitespace character as the default padding character.
|
||||
|
||||
```js
|
||||
const pad = (str, length, char = ' ') =>
|
||||
str.padStart((str.length + length) / 2, char).padEnd(length, char);
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Examples</summary>
|
||||
|
||||
```js
|
||||
pad('cat', 8); // ' cat '
|
||||
pad(String(42), 6, '0'); // '004200'
|
||||
pad('foobar', 3); // 'foobar'
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### palindrome
|
||||
|
||||
Returns `true` if the given string is a palindrome, `false` otherwise.
|
||||
@ -7023,6 +7121,42 @@ splitLines('This\nis a\nmultiline\nstring.\n'); // ['This', 'is a', 'multiline',
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### stringPermutations
|
||||
|
||||
⚠️ **WARNING**: This function's execution time increases exponentially with each character. Anything more than 8 to 10 characters will cause your browser to hang as it tries to solve all the different combinations.
|
||||
|
||||
Generates all permutations of a string (contains duplicates).
|
||||
|
||||
Use recursion.
|
||||
For each letter in the given string, create all the partial permutations for the rest of its letters.
|
||||
Use `Array.map()` to combine the letter with each partial permutation, then `Array.reduce()` to combine all permutations in one array.
|
||||
Base cases are for string `length` equal to `2` or `1`.
|
||||
|
||||
```js
|
||||
const stringPermutations = str => {
|
||||
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
|
||||
return str
|
||||
.split('')
|
||||
.reduce(
|
||||
(acc, letter, i) =>
|
||||
acc.concat(stringPermutations(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)),
|
||||
[]
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Examples</summary>
|
||||
|
||||
```js
|
||||
stringPermutations('abc'); // ['abc','acb','bac','bca','cab','cba']
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<br>[⬆ Back to top](#table-of-contents)
|
||||
|
||||
|
||||
### stripHTMLTags
|
||||
|
||||
Removes HTML/XML tags from string.
|
||||
|
||||
134
dist/_30s.es5.js
vendored
134
dist/_30s.es5.js
vendored
File diff suppressed because one or more lines are too long
2
dist/_30s.es5.min.js
vendored
2
dist/_30s.es5.min.js
vendored
File diff suppressed because one or more lines are too long
46
dist/_30s.esm.js
vendored
46
dist/_30s.esm.js
vendored
@ -27,17 +27,6 @@ const UUIDGeneratorNode = () =>
|
||||
|
||||
const all = (arr, fn = Boolean) => arr.every(fn);
|
||||
|
||||
const anagrams = str => {
|
||||
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
|
||||
return str
|
||||
.split('')
|
||||
.reduce(
|
||||
(acc, letter, i) =>
|
||||
acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)),
|
||||
[]
|
||||
);
|
||||
};
|
||||
|
||||
const any = (arr, fn = Boolean) => arr.some(fn);
|
||||
|
||||
const approximatelyEqual = (v1, v2, epsilon = 0.001) => Math.abs(v1 - v2) < epsilon;
|
||||
@ -607,6 +596,17 @@ const is = (type, val) => val instanceof type;
|
||||
|
||||
const isAbsoluteURL = str => /^[a-z][a-z0-9+.-]*:/.test(str);
|
||||
|
||||
const isAnagram = (str1, str2) => {
|
||||
const normalize = str =>
|
||||
str
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]/gi, '')
|
||||
.split('')
|
||||
.sort()
|
||||
.join('');
|
||||
return normalize(str1) === normalize(str2);
|
||||
};
|
||||
|
||||
const isArrayLike = val => {
|
||||
try {
|
||||
return [...val], true;
|
||||
@ -910,6 +910,17 @@ const partition = (arr, fn) =>
|
||||
const percentile = (arr, val) =>
|
||||
100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length;
|
||||
|
||||
const permutations = arr => {
|
||||
if (arr.length <= 2) return arr.length === 2 ? [arr, [arr[1], arr[0]]] : arr;
|
||||
return arr.reduce(
|
||||
(acc, item, i) =>
|
||||
acc.concat(
|
||||
permutations([...arr.slice(0, i), ...arr.slice(i + 1)]).map(val => [item, ...val])
|
||||
),
|
||||
[]
|
||||
);
|
||||
};
|
||||
|
||||
const pick = (obj, arr) =>
|
||||
arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});
|
||||
|
||||
@ -1174,6 +1185,17 @@ const standardDeviation = (arr, usePopulation = false) => {
|
||||
);
|
||||
};
|
||||
|
||||
const stringPermutations = str => {
|
||||
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
|
||||
return str
|
||||
.split('')
|
||||
.reduce(
|
||||
(acc, letter, i) =>
|
||||
acc.concat(stringPermutations(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)),
|
||||
[]
|
||||
);
|
||||
};
|
||||
|
||||
const stripHTMLTags = str => str.replace(/<[^>]*>/g, '');
|
||||
|
||||
const sum = (...arr) => [...arr].reduce((acc, val) => acc + val, 0);
|
||||
@ -1423,6 +1445,6 @@ const zipWith = (...arrays) => {
|
||||
return fn ? result.map(arr => fn(...arr)) : result;
|
||||
};
|
||||
|
||||
var imports = {JSONToFile,RGBToHex,URLJoin,UUIDGeneratorBrowser,UUIDGeneratorNode,all,anagrams,any,approximatelyEqual,arrayToHtmlList,ary,atob,attempt,average,averageBy,bifurcate,bifurcateBy,bind,bindAll,bindKey,binomialCoefficient,bottomVisible,btoa,byteSize,call,capitalize,capitalizeEveryWord,castArray,chainAsync,chunk,clampNumber,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,composeRight,converge,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,debounce,decapitalize,deepClone,deepFlatten,defaults,defer,degreesToRads,delay,detectDeviceType,difference,differenceBy,differenceWith,digitize,distance,drop,dropRight,dropRightWhile,dropWhile,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findKey,findLast,findLastIndex,findLastKey,flatten,flattenObject,flip,forEachRight,forOwn,forOwnRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,get,getColonTimeFromDate,getDaysDiffBetweenDates,getMeridiemSuffixOfInteger,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,mostPerformant,negate,none,nthArg,nthElement,objectFromPairs,objectToPairs,observeMutations,off,omit,omitBy,on,onUserInputChange,once,orderBy,over,overArgs,palindrome,parseCookie,partial,partialRight,partition,percentile,pick,pickBy,pipeAsyncFunctions,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,pullBy,radsToDegrees,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,rearg,redirect,reduceSuccessive,reduceWhich,reducedFilter,remove,removeNonASCII,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,sortedIndexBy,sortedLastIndex,sortedLastIndexBy,splitLines,spreadOver,stableSort,standardDeviation,stripHTMLTags,sum,sumBy,sumPower,symmetricDifference,symmetricDifferenceBy,symmetricDifferenceWith,tail,take,takeRight,takeRightWhile,takeWhile,throttle,timeTaken,times,toCamelCase,toCurrency,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unary,uncurry,unescapeHTML,unflattenObject,unfold,union,unionBy,unionWith,uniqueElements,untildify,unzip,unzipWith,validateNumber,without,words,xProd,yesNo,zip,zipObject,zipWith,}
|
||||
var imports = {JSONToFile,RGBToHex,URLJoin,UUIDGeneratorBrowser,UUIDGeneratorNode,all,any,approximatelyEqual,arrayToHtmlList,ary,atob,attempt,average,averageBy,bifurcate,bifurcateBy,bind,bindAll,bindKey,binomialCoefficient,bottomVisible,btoa,byteSize,call,capitalize,capitalizeEveryWord,castArray,chainAsync,chunk,clampNumber,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,composeRight,converge,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,debounce,decapitalize,deepClone,deepFlatten,defaults,defer,degreesToRads,delay,detectDeviceType,difference,differenceBy,differenceWith,digitize,distance,drop,dropRight,dropRightWhile,dropWhile,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findKey,findLast,findLastIndex,findLastKey,flatten,flattenObject,flip,forEachRight,forOwn,forOwnRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,get,getColonTimeFromDate,getDaysDiffBetweenDates,getMeridiemSuffixOfInteger,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,isAnagram,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,mostPerformant,negate,none,nthArg,nthElement,objectFromPairs,objectToPairs,observeMutations,off,omit,omitBy,on,onUserInputChange,once,orderBy,over,overArgs,palindrome,parseCookie,partial,partialRight,partition,percentile,permutations,pick,pickBy,pipeAsyncFunctions,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,pullBy,radsToDegrees,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,rearg,redirect,reduceSuccessive,reduceWhich,reducedFilter,remove,removeNonASCII,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,sortedIndexBy,sortedLastIndex,sortedLastIndexBy,splitLines,spreadOver,stableSort,standardDeviation,stringPermutations,stripHTMLTags,sum,sumBy,sumPower,symmetricDifference,symmetricDifferenceBy,symmetricDifferenceWith,tail,take,takeRight,takeRightWhile,takeWhile,throttle,timeTaken,times,toCamelCase,toCurrency,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unary,uncurry,unescapeHTML,unflattenObject,unfold,union,unionBy,unionWith,uniqueElements,untildify,unzip,unzipWith,validateNumber,without,words,xProd,yesNo,zip,zipObject,zipWith,}
|
||||
|
||||
export default imports;
|
||||
|
||||
46
dist/_30s.js
vendored
46
dist/_30s.js
vendored
@ -33,17 +33,6 @@ const UUIDGeneratorNode = () =>
|
||||
|
||||
const all = (arr, fn = Boolean) => arr.every(fn);
|
||||
|
||||
const anagrams = str => {
|
||||
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
|
||||
return str
|
||||
.split('')
|
||||
.reduce(
|
||||
(acc, letter, i) =>
|
||||
acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)),
|
||||
[]
|
||||
);
|
||||
};
|
||||
|
||||
const any = (arr, fn = Boolean) => arr.some(fn);
|
||||
|
||||
const approximatelyEqual = (v1, v2, epsilon = 0.001) => Math.abs(v1 - v2) < epsilon;
|
||||
@ -613,6 +602,17 @@ const is = (type, val) => val instanceof type;
|
||||
|
||||
const isAbsoluteURL = str => /^[a-z][a-z0-9+.-]*:/.test(str);
|
||||
|
||||
const isAnagram = (str1, str2) => {
|
||||
const normalize = str =>
|
||||
str
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]/gi, '')
|
||||
.split('')
|
||||
.sort()
|
||||
.join('');
|
||||
return normalize(str1) === normalize(str2);
|
||||
};
|
||||
|
||||
const isArrayLike = val => {
|
||||
try {
|
||||
return [...val], true;
|
||||
@ -916,6 +916,17 @@ const partition = (arr, fn) =>
|
||||
const percentile = (arr, val) =>
|
||||
100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length;
|
||||
|
||||
const permutations = arr => {
|
||||
if (arr.length <= 2) return arr.length === 2 ? [arr, [arr[1], arr[0]]] : arr;
|
||||
return arr.reduce(
|
||||
(acc, item, i) =>
|
||||
acc.concat(
|
||||
permutations([...arr.slice(0, i), ...arr.slice(i + 1)]).map(val => [item, ...val])
|
||||
),
|
||||
[]
|
||||
);
|
||||
};
|
||||
|
||||
const pick = (obj, arr) =>
|
||||
arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});
|
||||
|
||||
@ -1180,6 +1191,17 @@ const standardDeviation = (arr, usePopulation = false) => {
|
||||
);
|
||||
};
|
||||
|
||||
const stringPermutations = str => {
|
||||
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
|
||||
return str
|
||||
.split('')
|
||||
.reduce(
|
||||
(acc, letter, i) =>
|
||||
acc.concat(stringPermutations(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)),
|
||||
[]
|
||||
);
|
||||
};
|
||||
|
||||
const stripHTMLTags = str => str.replace(/<[^>]*>/g, '');
|
||||
|
||||
const sum = (...arr) => [...arr].reduce((acc, val) => acc + val, 0);
|
||||
@ -1429,7 +1451,7 @@ const zipWith = (...arrays) => {
|
||||
return fn ? result.map(arr => fn(...arr)) : result;
|
||||
};
|
||||
|
||||
var imports = {JSONToFile,RGBToHex,URLJoin,UUIDGeneratorBrowser,UUIDGeneratorNode,all,anagrams,any,approximatelyEqual,arrayToHtmlList,ary,atob,attempt,average,averageBy,bifurcate,bifurcateBy,bind,bindAll,bindKey,binomialCoefficient,bottomVisible,btoa,byteSize,call,capitalize,capitalizeEveryWord,castArray,chainAsync,chunk,clampNumber,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,composeRight,converge,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,debounce,decapitalize,deepClone,deepFlatten,defaults,defer,degreesToRads,delay,detectDeviceType,difference,differenceBy,differenceWith,digitize,distance,drop,dropRight,dropRightWhile,dropWhile,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findKey,findLast,findLastIndex,findLastKey,flatten,flattenObject,flip,forEachRight,forOwn,forOwnRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,get,getColonTimeFromDate,getDaysDiffBetweenDates,getMeridiemSuffixOfInteger,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,mostPerformant,negate,none,nthArg,nthElement,objectFromPairs,objectToPairs,observeMutations,off,omit,omitBy,on,onUserInputChange,once,orderBy,over,overArgs,palindrome,parseCookie,partial,partialRight,partition,percentile,pick,pickBy,pipeAsyncFunctions,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,pullBy,radsToDegrees,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,rearg,redirect,reduceSuccessive,reduceWhich,reducedFilter,remove,removeNonASCII,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,sortedIndexBy,sortedLastIndex,sortedLastIndexBy,splitLines,spreadOver,stableSort,standardDeviation,stripHTMLTags,sum,sumBy,sumPower,symmetricDifference,symmetricDifferenceBy,symmetricDifferenceWith,tail,take,takeRight,takeRightWhile,takeWhile,throttle,timeTaken,times,toCamelCase,toCurrency,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unary,uncurry,unescapeHTML,unflattenObject,unfold,union,unionBy,unionWith,uniqueElements,untildify,unzip,unzipWith,validateNumber,without,words,xProd,yesNo,zip,zipObject,zipWith,}
|
||||
var imports = {JSONToFile,RGBToHex,URLJoin,UUIDGeneratorBrowser,UUIDGeneratorNode,all,any,approximatelyEqual,arrayToHtmlList,ary,atob,attempt,average,averageBy,bifurcate,bifurcateBy,bind,bindAll,bindKey,binomialCoefficient,bottomVisible,btoa,byteSize,call,capitalize,capitalizeEveryWord,castArray,chainAsync,chunk,clampNumber,cloneRegExp,coalesce,coalesceFactory,collectInto,colorize,compact,compose,composeRight,converge,copyToClipboard,countBy,countOccurrences,createElement,createEventHub,currentURL,curry,debounce,decapitalize,deepClone,deepFlatten,defaults,defer,degreesToRads,delay,detectDeviceType,difference,differenceBy,differenceWith,digitize,distance,drop,dropRight,dropRightWhile,dropWhile,elementIsVisibleInViewport,elo,equals,escapeHTML,escapeRegExp,everyNth,extendHex,factorial,fibonacci,filterNonUnique,findKey,findLast,findLastIndex,findLastKey,flatten,flattenObject,flip,forEachRight,forOwn,forOwnRight,formatDuration,fromCamelCase,functionName,functions,gcd,geometricProgression,get,getColonTimeFromDate,getDaysDiffBetweenDates,getMeridiemSuffixOfInteger,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,isAnagram,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,mostPerformant,negate,none,nthArg,nthElement,objectFromPairs,objectToPairs,observeMutations,off,omit,omitBy,on,onUserInputChange,once,orderBy,over,overArgs,palindrome,parseCookie,partial,partialRight,partition,percentile,permutations,pick,pickBy,pipeAsyncFunctions,pipeFunctions,pluralize,powerset,prettyBytes,primes,promisify,pull,pullAtIndex,pullAtValue,pullBy,radsToDegrees,randomHexColorCode,randomIntArrayInRange,randomIntegerInRange,randomNumberInRange,readFileLines,rearg,redirect,reduceSuccessive,reduceWhich,reducedFilter,remove,removeNonASCII,reverseString,round,runAsync,runPromisesInSeries,sample,sampleSize,scrollToTop,sdbm,serializeCookie,setStyle,shallowClone,show,shuffle,similarity,size,sleep,sortCharactersInString,sortedIndex,sortedIndexBy,sortedLastIndex,sortedLastIndexBy,splitLines,spreadOver,stableSort,standardDeviation,stringPermutations,stripHTMLTags,sum,sumBy,sumPower,symmetricDifference,symmetricDifferenceBy,symmetricDifferenceWith,tail,take,takeRight,takeRightWhile,takeWhile,throttle,timeTaken,times,toCamelCase,toCurrency,toDecimalMark,toKebabCase,toOrdinalSuffix,toSafeInteger,toSnakeCase,toggleClass,tomorrow,transform,truncateString,truthCheckCollection,unary,uncurry,unescapeHTML,unflattenObject,unfold,union,unionBy,unionWith,uniqueElements,untildify,unzip,unzipWith,validateNumber,without,words,xProd,yesNo,zip,zipObject,zipWith,}
|
||||
|
||||
return imports;
|
||||
|
||||
|
||||
2
dist/_30s.min.js
vendored
2
dist/_30s.min.js
vendored
File diff suppressed because one or more lines are too long
111
docs/index.html
111
docs/index.html
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -92,7 +92,7 @@ $button-hover-border-color-var: '--btn-h-br-col';
|
||||
$button-group-border-color-var: '--btn-grp-br-col';
|
||||
|
||||
|
||||
$_include-fluid-input-group: false;
|
||||
$_include-fluid-input-group: true;
|
||||
|
||||
@import 'input_control';
|
||||
|
||||
@ -159,6 +159,9 @@ $_include-collapse: false;
|
||||
|
||||
@import 'contextual';
|
||||
|
||||
div,main,nav{
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
.#{$toast-name} {
|
||||
bottom: calc(var(#{$universal-margin-var}) / 2);
|
||||
opacity: 1;
|
||||
@ -195,68 +198,45 @@ pre {
|
||||
border: 0.0625rem solid var(#{$secondary-border-color-var});
|
||||
border-radius: var(#{$universal-border-radius-var});
|
||||
}
|
||||
.group{
|
||||
position:relative;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 1em
|
||||
}
|
||||
.search{
|
||||
|
||||
.search {
|
||||
font-size: 0.875rem;
|
||||
margin-top: -0.1em;
|
||||
display:block;
|
||||
width:100%;
|
||||
border:none;
|
||||
border-bottom: $__1px solid var(#{$nav-link-color-var});
|
||||
}
|
||||
.search:focus{
|
||||
outline:none
|
||||
}
|
||||
label#search-label{
|
||||
color:var(#{$nav-link-color-var});
|
||||
font-size: 1.125rem;
|
||||
font-weight:400;
|
||||
position:absolute;
|
||||
left: 0.3125rem;
|
||||
top: 0.625rem;
|
||||
}
|
||||
.search:focus ~ label#search-label,.search:valid ~ label#search-label{
|
||||
top: -1.25rem;
|
||||
font-size: 0.875rem;
|
||||
color:var(#{$nav-link-color-var});
|
||||
}
|
||||
label#menu-toggle {
|
||||
width: 3.4375rem;
|
||||
}
|
||||
|
||||
header h1.logo {
|
||||
margin-top: -0.8rem;
|
||||
text-align:center;
|
||||
position: relative;
|
||||
top: 0;
|
||||
transition: top 0.3s;
|
||||
a {
|
||||
text-decoration:none;
|
||||
color: #111;
|
||||
}
|
||||
@media screen and (min-width: 769px) {
|
||||
&:hover {
|
||||
top: -3.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
header #title {
|
||||
position:relative;
|
||||
top: -1rem;
|
||||
@media screen and (max-width: 500px) { font-size: 1rem; display: block }
|
||||
@media screen and (max-width: 768px) { display: none; }
|
||||
}
|
||||
|
||||
header h1 small {
|
||||
display:block;
|
||||
font-size: 0.875rem;
|
||||
color: #888;
|
||||
margin-top: -0.8rem;
|
||||
@media screen and (max-width: 768px) { font-size: 0.75rem; }
|
||||
@media screen and (max-width: 600px) { font-size: 0.625rem; }
|
||||
@media screen and (max-width: 500px) { font-size: 0.5rem; margin-top: -1.2rem; }
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
label#menu-toggle {
|
||||
position: absolute;
|
||||
left: 0.5rem;
|
||||
top: 0.5rem;
|
||||
left: 0rem;
|
||||
top: 0rem;
|
||||
width: 3.4375rem;
|
||||
}
|
||||
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
### anagrams
|
||||
|
||||
⚠️ **WARNING**: This function's execution time increases exponentially with each character. Anything more than 8 to 10 characters will cause your browser to hang as it tries to solve all the different combinations.
|
||||
|
||||
Generates all anagrams of a string (contains duplicates).
|
||||
|
||||
Use recursion.
|
||||
For each letter in the given string, create all the partial anagrams for the rest of its letters.
|
||||
Use `Array.map()` to combine the letter with each partial anagram, then `Array.reduce()` to combine all anagrams in one array.
|
||||
Base cases are for string `length` equal to `2` or `1`.
|
||||
|
||||
```js
|
||||
const anagrams = str => {
|
||||
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
|
||||
return str
|
||||
.split('')
|
||||
.reduce(
|
||||
(acc, letter, i) =>
|
||||
acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)),
|
||||
[]
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
anagrams('abc'); // ['abc','acb','bac','bca','cab','cba']
|
||||
```
|
||||
22
snippets/isAnagram.md
Normal file
22
snippets/isAnagram.md
Normal file
@ -0,0 +1,22 @@
|
||||
### isAnagram
|
||||
|
||||
Checks if a string is an anagram of another string (case-insensitive, ignores spaces, punctuation and special characters).
|
||||
|
||||
Use `String.toLowerCase()`, `String.replace()` with an appropriate regular expression to remove unnecessary characters, `String.split('')`, `Array.sort()` and `Array.join('')` on both strings to normalize them, then check if their normalized forms are equal.
|
||||
|
||||
```js
|
||||
const isAnagram = (str1, str2) => {
|
||||
const normalize = str =>
|
||||
str
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]/gi, '')
|
||||
.split('')
|
||||
.sort()
|
||||
.join('');
|
||||
return normalize(str1) === normalize(str2);
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
isAnagram('iceman', 'cinema'); // true
|
||||
```
|
||||
29
snippets/nest.md
Normal file
29
snippets/nest.md
Normal file
@ -0,0 +1,29 @@
|
||||
### nest
|
||||
|
||||
Given a flat array of objects linked to one another, it will nest them recursively.
|
||||
Useful for nesting comments, such as the ones on reddit.com.
|
||||
|
||||
Use recursion.
|
||||
Use `Array.filter()` to filter the items where the `id` matches the `link`, then `Array.map()` to map each one to a new object that has a `children` property which recursively nests the items based on which ones are children of the current item.
|
||||
Omit the second argument, `id`, to default to `null` which indicates the object is not linked to another one (i.e. it is a top level object).
|
||||
Omit the third argument, `link`, to use `'parent_id'` as the default property which links the object to another one by its `id`.
|
||||
|
||||
```js
|
||||
const nest = (items, id = null, link = 'parent_id') =>
|
||||
items
|
||||
.filter(item => item[link] === id)
|
||||
.map(item => ({ ...item, children: nest(items, item.id) }));
|
||||
```
|
||||
|
||||
```js
|
||||
// One top level comment
|
||||
const comments = [
|
||||
{ id: 1, parent_id: null },
|
||||
{ id: 2, parent_id: 1 },
|
||||
{ id: 3, parent_id: 1 },
|
||||
{ id: 4, parent_id: 2 },
|
||||
{ id: 5, parent_id: 4 }
|
||||
];
|
||||
const nestedComments = nest(comments); // [{ id: 1, parent_id: null, children: [...] }]
|
||||
```
|
||||
|
||||
17
snippets/pad.md
Normal file
17
snippets/pad.md
Normal file
@ -0,0 +1,17 @@
|
||||
### pad
|
||||
|
||||
Pads a string on both sides with the specified character, if it's shorter than the specified length.
|
||||
|
||||
Use `String.padStart()` and `String.padEnd()` to pad both sides of the given string.
|
||||
Omit the third argument, `char`, to use the whitespace character as the default padding character.
|
||||
|
||||
```js
|
||||
const pad = (str, length, char = ' ') =>
|
||||
str.padStart((str.length + length) / 2, char).padEnd(length, char);
|
||||
```
|
||||
|
||||
```js
|
||||
pad('cat', 8); // ' cat '
|
||||
pad(String(42), 6, '0'); // '004200'
|
||||
pad('foobar', 3); // 'foobar'
|
||||
```
|
||||
27
snippets/permutations.md
Normal file
27
snippets/permutations.md
Normal file
@ -0,0 +1,27 @@
|
||||
### permutations
|
||||
|
||||
⚠️ **WARNING**: This function's execution time increases exponentially with each array element. Anything more than 8 to 10 entries will cause your browser to hang as it tries to solve all the different combinations.
|
||||
|
||||
Generates all permutations of an array's elements (contains duplicates).
|
||||
|
||||
Use recursion.
|
||||
For each element in the given array, create all the partial permutations for the rest of its elements.
|
||||
Use `Array.map()` to combine the element with each partial permutation, then `Array.reduce()` to combine all permutations in one array.
|
||||
Base cases are for array `length` equal to `2` or `1`.
|
||||
|
||||
```js
|
||||
const permutations = arr => {
|
||||
if (arr.length <= 2) return arr.length === 2 ? [arr, [arr[1], arr[0]]] : arr;
|
||||
return arr.reduce(
|
||||
(acc, item, i) =>
|
||||
acc.concat(
|
||||
permutations([...arr.slice(0, i), ...arr.slice(i + 1)]).map(val => [item, ...val])
|
||||
),
|
||||
[]
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
permutations([1, 33, 5]); // [ [ 1, 33, 5 ], [ 1, 5, 33 ], [ 33, 1, 5 ], [ 33, 5, 1 ], [ 5, 1, 33 ], [ 5, 33, 1 ] ]
|
||||
```
|
||||
@ -3,16 +3,12 @@
|
||||
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.reverse()` and `Array.findIndex()` to find the appropriate last index where the element should be inserted.
|
||||
|
||||
```js
|
||||
const sortedLastIndex = (arr, n) => {
|
||||
const isDescending = arr[0] > arr[arr.length - 1];
|
||||
const index = arr
|
||||
.map((val, i) => [i, val])
|
||||
.reverse()
|
||||
.findIndex(el => (isDescending ? n <= el[1] : n >= el[1]));
|
||||
const index = arr.reverse().findIndex(el => (isDescending ? n <= el : n >= el));
|
||||
return index === -1 ? 0 : arr.length - index - 1;
|
||||
};
|
||||
```
|
||||
|
||||
@ -3,16 +3,17 @@
|
||||
Returns the highest index at which value should be inserted into array in order to maintain its sort order, based on a provided iterator function.
|
||||
|
||||
Check if the array is sorted in descending order (loosely).
|
||||
Use `Array.reverse()` and `Array.findIndex()` to find the appropriate last index where the element should be inserted, based on the iterator function `fn`..
|
||||
Use `Array.map()` to apply the iterator function to all elements of the array.
|
||||
Use `Array.reverse()` and `Array.findIndex()` to find the appropriate last index where the element should be inserted, based on the provided iterator function.
|
||||
|
||||
```js
|
||||
const sortedLastIndexBy = (arr, n, fn) => {
|
||||
const isDescending = fn(arr[0]) > fn(arr[arr.length - 1]);
|
||||
const val = fn(n);
|
||||
const index = arr
|
||||
.map((val, i) => [i, fn(val)])
|
||||
.map(fn)
|
||||
.reverse()
|
||||
.findIndex(el => (isDescending ? val <= el[1] : val >= el[1]));
|
||||
.findIndex(el => (isDescending ? val <= el : val >= el));
|
||||
return index === -1 ? 0 : arr.length - index;
|
||||
};
|
||||
```
|
||||
|
||||
27
snippets/stringPermutations.md
Normal file
27
snippets/stringPermutations.md
Normal file
@ -0,0 +1,27 @@
|
||||
### stringPermutations
|
||||
|
||||
⚠️ **WARNING**: This function's execution time increases exponentially with each character. Anything more than 8 to 10 characters will cause your browser to hang as it tries to solve all the different combinations.
|
||||
|
||||
Generates all permutations of a string (contains duplicates).
|
||||
|
||||
Use recursion.
|
||||
For each letter in the given string, create all the partial permutations for the rest of its letters.
|
||||
Use `Array.map()` to combine the letter with each partial permutation, then `Array.reduce()` to combine all permutations in one array.
|
||||
Base cases are for string `length` equal to `2` or `1`.
|
||||
|
||||
```js
|
||||
const stringPermutations = str => {
|
||||
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
|
||||
return str
|
||||
.split('')
|
||||
.reduce(
|
||||
(acc, letter, i) =>
|
||||
acc.concat(stringPermutations(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)),
|
||||
[]
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
stringPermutations('abc'); // ['abc','acb','bac','bca','cab','cba']
|
||||
```
|
||||
@ -4,15 +4,17 @@ Results in a string representation of tomorrow's date.
|
||||
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 = () => {
|
||||
const tomorrow = (long = false) => {
|
||||
let t = new Date();
|
||||
t.setDate(t.getDate() + 1);
|
||||
return `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, '0')}-${String(
|
||||
const ret = `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, '0')}-${String(
|
||||
t.getDate()
|
||||
).padStart(2, '0')}`;
|
||||
return !long ? ret : `${ret}T00:00:00`;
|
||||
};
|
||||
```
|
||||
|
||||
```js
|
||||
tomorrow(); // 2017-12-27 (if current date is 2017-12-26)
|
||||
tomorrow(true); // 2017-12-27T00:00:00 (if current date is 2017-12-26)
|
||||
```
|
||||
|
||||
19
snippets_archive/isSimilar.md
Normal file
19
snippets_archive/isSimilar.md
Normal file
@ -0,0 +1,19 @@
|
||||
### isSimilar
|
||||
|
||||
Determines if the `pattern` matches with `str`.
|
||||
|
||||
Use `String.toLowerCase()` to convert both strings to lowercase, then loop through `str` and determine if it contains all characters of `pattern` and in the correct order.
|
||||
Adapted from [here](https://github.com/forrestthewoods/lib_fts/blob/80f3f8c52db53428247e741b9efe2cde9667050c/code/fts_fuzzy_match.js#L18).
|
||||
|
||||
``` js
|
||||
const isSimilar = (pattern, str) =>
|
||||
[...str].reduce(
|
||||
(matchIndex, char) => char.toLowerCase() === (pattern[matchIndex] || '').toLowerCase() ? matchIndex + 1 : matchIndex, 0
|
||||
) === pattern.length ? true : false;
|
||||
```
|
||||
|
||||
|
||||
``` js
|
||||
isSimilar('rt','Rohit'); // true
|
||||
isSimilar('tr','Rohit'); // false
|
||||
```
|
||||
@ -34,11 +34,30 @@
|
||||
document.querySelector('main').scrollTo(0, c - c / 4);
|
||||
}
|
||||
};
|
||||
function scrollTo(element, to, id, duration) {
|
||||
if (duration <= 0) return;
|
||||
var difference = to - element.scrollTop;
|
||||
var perTick = difference / duration * 40;
|
||||
|
||||
setTimeout(function() {
|
||||
element.scrollTop = element.scrollTop + perTick;
|
||||
if (element.scrollTop === to) {
|
||||
window.location.href = "#"+id;
|
||||
return;
|
||||
}
|
||||
scrollTo(element, to, id, duration - 40);
|
||||
}, 40);
|
||||
};
|
||||
function loader() {
|
||||
registerClickListener();
|
||||
}
|
||||
function registerClickListener() {
|
||||
document.addEventListener('click', function (event) {
|
||||
if( document.getElementById('doc-drawer-checkbox').checked ) {
|
||||
if(!document.querySelector('nav').contains(event.target) && !event.target.classList.contains('drawer-toggle') && !event.target.classList.contains('drawer')) {
|
||||
document.getElementById('doc-drawer-checkbox').checked = false;
|
||||
}
|
||||
}
|
||||
if ( event.target.classList.contains('collapse') ) {
|
||||
event.target.classList = event.target.classList.contains('toggled') ? 'collapse' : 'collapse toggled';
|
||||
}
|
||||
@ -64,23 +83,26 @@
|
||||
else if (event.target.classList.contains('scroll-to-top')){
|
||||
scrollToTop();
|
||||
}
|
||||
else if (event.target.classList.contains('sublink-1')){
|
||||
event.preventDefault();
|
||||
scrollTo(document.querySelector('main'), document.getElementById(event.target.href.split('#')[1]).parentElement.offsetTop - 60, event.target.href.split('#')[1], 400);
|
||||
document.getElementById('doc-drawer-checkbox').checked = false;
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="loader()">
|
||||
<a href="https://github.com/Chalarangelo/30-seconds-of-code" class="github-corner" aria-label="View source on Github"><svg width="90" height="90" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
|
||||
<header style="height: 5.5rem;">
|
||||
<h1 class="logo"><img src="favicon.png" style="height: 4rem;" alt="logo"/><span id="title"> 30 seconds of code</span>
|
||||
<a href="https://github.com/Chalarangelo/30-seconds-of-code" class="github-corner" aria-label="View source on Github"><svg width="56" height="56" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0; z-index: 1000" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
|
||||
<header style="height: 3.5rem; box-sizing: border-box; overflow: hidden;">
|
||||
<h1 class="logo"><img src="favicon.png" style="height: 3.5rem;" alt="logo"/><span id="title"> 30 seconds of code</span>
|
||||
<small>Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.</small>
|
||||
</h1>
|
||||
<label for="doc-drawer-checkbox" class="button drawer-toggle" id="menu-toggle"></label>
|
||||
</header>
|
||||
<div class="row" style="height: calc(100vh - 5.875rem);overflow: hidden;">
|
||||
<div class="row" style="height: calc(100vh - 3.5rem);overflow: hidden;">
|
||||
<input id="doc-drawer-checkbox" class="drawer" value="on" type="checkbox">
|
||||
<nav class="col-md-4 col-lg-3" style="border-top: 0">
|
||||
<div class="group">
|
||||
<input class="search" type="text" id="searchInput" onkeyup="search(this)">
|
||||
<label id="search-label">Search for snippet...</label>
|
||||
<div class="input-group vertical">
|
||||
<input class="search" type="text" id="searchInput" onkeyup="search(this)" placeholder="Search...">
|
||||
</div>
|
||||
<label for="doc-drawer-checkbox" class="button drawer-close"></label>
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
all:array,function
|
||||
anagrams:string,recursion
|
||||
any:array,function
|
||||
approximatelyEqual:math
|
||||
arrayToHtmlList:browser,array
|
||||
@ -117,6 +116,7 @@ intersectionWith:array,function
|
||||
invertKeyValues:object,function
|
||||
is:type,array,regexp
|
||||
isAbsoluteURL:string,utility,browser,url
|
||||
isAnagram:string,regexp
|
||||
isArrayLike:type,array
|
||||
isBoolean:type
|
||||
isDivisible:math
|
||||
@ -162,6 +162,7 @@ minBy:math,array,function
|
||||
minN:array,math
|
||||
mostPerformant:utility,function
|
||||
negate:function
|
||||
nest:object
|
||||
none:array,function
|
||||
nthArg:utility,function
|
||||
nthElement:array
|
||||
@ -177,12 +178,14 @@ onUserInputChange:browser,event,advanced
|
||||
orderBy:object,array
|
||||
over:adapter,function
|
||||
overArgs:adapter,function
|
||||
pad:string
|
||||
palindrome:string
|
||||
parseCookie:utility,string
|
||||
partial:function
|
||||
partialRight:function
|
||||
partition:array,object,function
|
||||
percentile:math
|
||||
permutations:array,recursion
|
||||
pick:object,array
|
||||
pickBy:object,array,function
|
||||
pipeAsyncFunctions:adapter,function,promise
|
||||
@ -235,6 +238,7 @@ splitLines:string
|
||||
spreadOver:adapter
|
||||
stableSort:array,sort,advanced
|
||||
standardDeviation:math,array
|
||||
stringPermutations:string,recursion
|
||||
stripHTMLTags:string,utility,regexp
|
||||
sum:math,array
|
||||
sumBy:math,array,function
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
const anagrams = str => {
|
||||
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
|
||||
return str
|
||||
.split('')
|
||||
.reduce(
|
||||
(acc, letter, i) =>
|
||||
acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)),
|
||||
[]
|
||||
);
|
||||
};
|
||||
module.exports = anagrams;
|
||||
@ -1,16 +0,0 @@
|
||||
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('a'), ['a'], "Works for single-letter strings");
|
||||
t.deepEqual(anagrams(''), [''], "Works for empty strings");
|
||||
//t.deepEqual(anagrams(args..), 'Expected');
|
||||
//t.equal(anagrams(args..), 'Expected');
|
||||
//t.false(anagrams(args..), 'Expected');
|
||||
//t.throws(anagrams(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
11
test/isAnagram/isAnagram.js
Normal file
11
test/isAnagram/isAnagram.js
Normal file
@ -0,0 +1,11 @@
|
||||
const isAnagram = (str1, str2) => {
|
||||
const normalize = str =>
|
||||
str
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]/gi, '')
|
||||
.split('')
|
||||
.sort()
|
||||
.join('');
|
||||
return normalize(str1) === normalize(str2);
|
||||
};
|
||||
module.exports = isAnagram;
|
||||
17
test/isAnagram/isAnagram.test.js
Normal file
17
test/isAnagram/isAnagram.test.js
Normal file
@ -0,0 +1,17 @@
|
||||
const test = require('tape');
|
||||
const isAnagram = require('./isAnagram.js');
|
||||
|
||||
test('Testing isAnagram', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof isAnagram === 'function', 'isAnagram is a Function');
|
||||
t.true(isAnagram('iceman', 'cinema'), 'Checks valid anagram');
|
||||
t.true(isAnagram('rail safety', 'fairy tales'), 'Works with spaces');
|
||||
t.true(isAnagram('roast beef', 'eat for BSE'), 'Ignores case');
|
||||
t.true(isAnagram('Regera Dowdy', 'E. G. Deadworry'), 'Ignores special characters');
|
||||
//t.deepEqual(isAnagram(args..), 'Expected');
|
||||
//t.equal(isAnagram(args..), 'Expected');
|
||||
//t.false(isAnagram(args..), 'Expected');
|
||||
//t.throws(isAnagram(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
5
test/nest/nest.js
Normal file
5
test/nest/nest.js
Normal file
@ -0,0 +1,5 @@
|
||||
const nest = (items, id = null, link = 'parent_id') =>
|
||||
items
|
||||
.filter(item => item[link] === id)
|
||||
.map(item => ({ ...item, children: nest(items, item.id) }));
|
||||
module.exports = nest;
|
||||
13
test/nest/nest.test.js
Normal file
13
test/nest/nest.test.js
Normal file
@ -0,0 +1,13 @@
|
||||
const test = require('tape');
|
||||
const nest = require('./nest.js');
|
||||
|
||||
test('Testing nest', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof nest === 'function', 'nest is a Function');
|
||||
//t.deepEqual(nest(args..), 'Expected');
|
||||
//t.equal(nest(args..), 'Expected');
|
||||
//t.false(nest(args..), 'Expected');
|
||||
//t.throws(nest(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
3
test/pad/pad.js
Normal file
3
test/pad/pad.js
Normal file
@ -0,0 +1,3 @@
|
||||
const pad = (string, length = 8, char = ' ') =>
|
||||
string.padStart((string.length + length) / 2, char).padEnd(length, char);
|
||||
module.exports = pad;
|
||||
13
test/pad/pad.test.js
Normal file
13
test/pad/pad.test.js
Normal file
@ -0,0 +1,13 @@
|
||||
const test = require('tape');
|
||||
const pad = require('./pad.js');
|
||||
|
||||
test('Testing pad', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof pad === 'function', 'pad is a Function');
|
||||
t.equal(pad('cat'), ' cat ', 'cat is padded on both sides');
|
||||
t.equal(pad('cat').length, 8, 'length of string is 8');
|
||||
t.equal(pad(String(42), 6, '0'), '004200', 'pads 42 with "0"');
|
||||
t.equal(pad('foobar', 3), 'foobar', 'does not truncates if string exceeds length');
|
||||
t.end();
|
||||
});
|
||||
11
test/permutations/permutations.js
Normal file
11
test/permutations/permutations.js
Normal file
@ -0,0 +1,11 @@
|
||||
const permutations = arr => {
|
||||
if (arr.length <= 2) return arr.length === 2 ? [arr, [arr[1], arr[0]]] : arr;
|
||||
return arr.reduce(
|
||||
(acc, item, i) =>
|
||||
acc.concat(
|
||||
permutations([...arr.slice(0, i), ...arr.slice(i + 1)]).map(val => [item, ...val])
|
||||
),
|
||||
[]
|
||||
);
|
||||
};
|
||||
module.exports = permutations;
|
||||
14
test/permutations/permutations.test.js
Normal file
14
test/permutations/permutations.test.js
Normal file
@ -0,0 +1,14 @@
|
||||
const test = require('tape');
|
||||
const permutations = require('./permutations.js');
|
||||
|
||||
test('Testing permutations', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof permutations === 'function', 'permutations is a Function');
|
||||
t.deepEqual(permutations([1, 33, 5]), [ [ 1, 33, 5 ], [ 1, 5, 33 ], [ 33, 1, 5 ], [ 33, 5, 1 ], [ 5, 1, 33 ], [ 5, 33, 1 ] ], 'Generates all permutations of an array');
|
||||
//t.deepEqual(permuteAll(args..), 'Expected');
|
||||
//t.equal(permuteAll(args..), 'Expected');
|
||||
//t.false(permuteAll(args..), 'Expected');
|
||||
//t.throws(permuteAll(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
11
test/stringPermutations/stringPermutations.js
Normal file
11
test/stringPermutations/stringPermutations.js
Normal file
@ -0,0 +1,11 @@
|
||||
const stringPermutations = str => {
|
||||
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
|
||||
return str
|
||||
.split('')
|
||||
.reduce(
|
||||
(acc, letter, i) =>
|
||||
acc.concat(stringPermutations(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)),
|
||||
[]
|
||||
);
|
||||
};
|
||||
module.exports = stringPermutations;
|
||||
16
test/stringPermutations/stringPermutations.test.js
Normal file
16
test/stringPermutations/stringPermutations.test.js
Normal file
@ -0,0 +1,16 @@
|
||||
const test = require('tape');
|
||||
const stringPermutations = require('./stringPermutations.js');
|
||||
|
||||
test('Testing stringPermutations', (t) => {
|
||||
//For more information on all the methods supported by tape
|
||||
//Please go to https://github.com/substack/tape
|
||||
t.true(typeof stringPermutations === 'function', 'stringPermutations is a Function');
|
||||
t.deepEqual(stringPermutations('abc'), ['abc','acb','bac','bca','cab','cba'], "Generates all stringPermutations of a string");
|
||||
t.deepEqual(stringPermutations('a'), ['a'], "Works for single-letter strings");
|
||||
t.deepEqual(stringPermutations(''), [''], "Works for empty strings");
|
||||
//t.deepEqual(anagrams(args..), 'Expected');
|
||||
//t.equal(anagrams(args..), 'Expected');
|
||||
//t.false(anagrams(args..), 'Expected');
|
||||
//t.throws(anagrams(args..), 'Expected');
|
||||
t.end();
|
||||
});
|
||||
@ -1,8 +1,9 @@
|
||||
const tomorrow = () => {
|
||||
const tomorrow = (long = false) => {
|
||||
let t = new Date();
|
||||
t.setDate(t.getDate() + 1);
|
||||
return `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, '0')}-${String(
|
||||
const ret = `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, '0')}-${String(
|
||||
t.getDate()
|
||||
).padStart(2, '0')}`;
|
||||
return !long ? ret : `${ret}T00:00:00`;
|
||||
};
|
||||
module.exports = tomorrow;
|
||||
Reference in New Issue
Block a user