diff --git a/.travis.yml b/.travis.yml
index 349290617..b33bb033d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,9 +11,8 @@ before_install:
script:
- npm run linter
- npm run extractor
-- npm run builder
- npm run packager
-- npm run tester
+- npm run test
- npm run vscoder
after_success:
- chmod +x .travis/push.sh
diff --git a/.travis/push.sh b/.travis/push.sh
index a74151106..b654bd67b 100755
--- a/.travis/push.sh
+++ b/.travis/push.sh
@@ -26,7 +26,7 @@ upload_files() {
if [ $TRAVIS_EVENT_TYPE != "pull_request" ]; then
if [ $TRAVIS_BRANCH == "master" ]; then
echo "Pushing to master branch..."
- git push --force --quiet "https://${GH_TOKEN}@github.com/30-seconds/30-seconds-of-code.git" master > /dev/null 2>&1
+ git push --quiet "https://${GH_TOKEN}@github.com/30-seconds/30-seconds-of-code.git" master > /dev/null 2>&1
fi
fi
}
diff --git a/README.md b/README.md
index 6486b3d57..d3999ee21 100644
--- a/README.md
+++ b/README.md
@@ -1,9731 +1,26 @@
-[](https://30secondsofcode.org/)
+[](https://30secondsofcode.org/js/p/1)
# 30 seconds of code
-[](https://github.com/30-seconds/30-seconds-of-code/blob/master/LICENSE) [](https://www.npmjs.com/package/30-seconds-of-code) [](https://www.npmjs.com/package/30-seconds-of-code) [](https://snyk.io/test/github/30-seconds/30-seconds-of-code?targetFile=package.json) [](https://travis-ci.com/30-seconds/30-seconds-of-code)
-[](https://awesome.re) [](https://www.producthunt.com/posts/30-seconds-of-code) [](https://github.com/Flet/semistandard) [](http://makeapullrequest.com)
+> Short JavaScript code snippets for all your development needs
-> Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.
+* Visit [our website](https://30secondsofcode.org) to view our snippet collection.
+* Use the [Search page](https://30secondsofcode.org/search) to find snippets that suit your needs. You can search by name, tag, language or using a snippet's description. Just start typing a term and see what comes up.
+* Browse the [JavaScript Snippet List](https://30secondsofcode.org/js/p/1) to see all the snippets in this project or click individual tags at the top of the same page to narrow down your search to a specific tag.
+* Click on each snippet card to view the whole snippet, including code, explanation and examples.
+* You can use the button on the right side of a snippet card to copy the code to clipboard.
+* If you like the project, give it a star. It means a lot to the people maintaining it.
-* Use Ctrl + F or command + F to search for a snippet.
-* Contributions welcome, please read the [contribution guide](CONTRIBUTING.md).
-* Snippets are written in ES6, use the [Babel transpiler](https://babeljs.io/) to ensure backwards-compatibility.
-* You can import these snippets into VSCode, by following the instructions found [here](https://github.com/30-seconds/30-seconds-of-code/tree/master/vscode_snippets).
-* You can search, view and copy these snippets from a terminal, using the CLI application from [this repo](https://github.com/sQVe/30s).
-* If you want to follow 30-seconds-of-code on social media, you can find us on [Facebook](https://www.facebook.com/30secondsofcode), [Instagram](https://www.instagram.com/30secondsofcode) and [Twitter](https://twitter.com/30secondsofcode).
+## Want to contribute?
-#### Related projects
+* If you want to help us improve, take a minute to read the [Contribution Guidelines](/CONTRIBUTING.md) first.
+* Use the [Snippet Template](/snippet-template.md) to add new snippets to the collection.
+* If you find a problem with a specific snippet, please [open an issue](https://github.com/30-seconds/30-seconds-of-code/issues/new).
+* If you find a problem with the website, please [report it in the web repository](https://github.com/30-seconds/30-seconds-web/issues/new).
-* [30 Seconds of CSS](https://30-seconds.github.io/30-seconds-of-css/)
-* [30 Seconds of Interviews](https://30secondsofinterviews.org/)
-* [30 Seconds of React](https://github.com/30-seconds/30-seconds-of-react)
-* [30 Seconds of Python](https://github.com/30-seconds/30-seconds-of-python-code)
-* [30 Seconds of PHP](https://github.com/30-seconds/30-seconds-of-php-code)
-* [30 Seconds of Knowledge](https://chrome.google.com/webstore/detail/30-seconds-of-knowledge/mmgplondnjekobonklacmemikcnhklla)
-* [30 Seconds of Kotlin](https://github.com/IvanMwiruki/30-seconds-of-kotlin) _(unofficial)_
-
-#### Package
-
-⚠️ **NOTICE:** A few of our snippets are not yet optimized for production (see disclaimers for individual snippet issues).
-
-You can find a package with all the snippets on [npm](https://www.npmjs.com/package/30-seconds-of-code).
-
-```bash
-# With npm
-npm install 30-seconds-of-code
-
-# With yarn
-yarn add 30-seconds-of-code
-```
-
-[CDN link](https://unpkg.com/30-seconds-of-code/)
-
-Details
-
-**Browser**
-
-```html
-
-
-```
-
-**Node**
-
-```js
-// CommonJS
-const _30s = require('30-seconds-of-code');
-_30s.average(1, 2, 3);
-
-// ES Modules
-import _30s from '30-seconds-of-code';
-_30s.average(1, 2, 3);
-```
-
-View contents
-
-* [`ary`](#ary)
-* [`call`](#call)
-* [`collectInto`](#collectinto)
-* [`flip`](#flip)
-* [`over`](#over)
-* [`overArgs`](#overargs)
-* [`pipeAsyncFunctions`](#pipeasyncfunctions)
-* [`pipeFunctions`](#pipefunctions)
-* [`promisify`](#promisify)
-* [`rearg`](#rearg)
-* [`spreadOver`](#spreadover)
-* [`unary`](#unary)
-
-View contents
-
-* [`all`](#all)
-* [`allEqual`](#allequal)
-* [`any`](#any)
-* [`arrayToCSV`](#arraytocsv)
-* [`bifurcate`](#bifurcate)
-* [`bifurcateBy`](#bifurcateby)
-* [`chunk`](#chunk)
-* [`compact`](#compact)
-* [`countBy`](#countby)
-* [`countOccurrences`](#countoccurrences)
-* [`deepFlatten`](#deepflatten)
-* [`difference`](#difference)
-* [`differenceBy`](#differenceby)
-* [`differenceWith`](#differencewith)
-* [`drop`](#drop)
-* [`dropRight`](#dropright)
-* [`dropRightWhile`](#droprightwhile)
-* [`dropWhile`](#dropwhile)
-* [`everyNth`](#everynth)
-* [`filterFalsy`](#filterfalsy)
-* [`filterNonUnique`](#filternonunique)
-* [`filterNonUniqueBy`](#filternonuniqueby)
-* [`findLast`](#findlast)
-* [`findLastIndex`](#findlastindex)
-* [`flatten`](#flatten)
-* [`forEachRight`](#foreachright)
-* [`groupBy`](#groupby)
-* [`head`](#head)
-* [`includesAll`](#includesall)
-* [`includesAny`](#includesany)
-* [`indexOfAll`](#indexofall)
-* [`initial`](#initial)
-* [`initialize2DArray`](#initialize2darray)
-* [`initializeArrayWithRange`](#initializearraywithrange)
-* [`initializeArrayWithRangeRight`](#initializearraywithrangeright)
-* [`initializeArrayWithValues`](#initializearraywithvalues)
-* [`initializeNDArray`](#initializendarray)
-* [`intersection`](#intersection)
-* [`intersectionBy`](#intersectionby)
-* [`intersectionWith`](#intersectionwith)
-* [`isSorted`](#issorted)
-* [`join`](#join)
-* [`JSONtoCSV`](#jsontocsv-)
-* [`last`](#last)
-* [`longestItem`](#longestitem)
-* [`mapObject`](#mapobject-)
-* [`maxN`](#maxn)
-* [`minN`](#minn)
-* [`none`](#none)
-* [`nthElement`](#nthelement)
-* [`offset`](#offset)
-* [`partition`](#partition)
-* [`permutations`](#permutations-)
-* [`pull`](#pull)
-* [`pullAtIndex`](#pullatindex-)
-* [`pullAtValue`](#pullatvalue-)
-* [`pullBy`](#pullby-)
-* [`reducedFilter`](#reducedfilter)
-* [`reduceSuccessive`](#reducesuccessive)
-* [`reduceWhich`](#reducewhich)
-* [`reject`](#reject)
-* [`remove`](#remove)
-* [`sample`](#sample)
-* [`sampleSize`](#samplesize)
-* [`shank`](#shank)
-* [`shuffle`](#shuffle)
-* [`similarity`](#similarity)
-* [`sortedIndex`](#sortedindex)
-* [`sortedIndexBy`](#sortedindexby)
-* [`sortedLastIndex`](#sortedlastindex)
-* [`sortedLastIndexBy`](#sortedlastindexby)
-* [`stableSort`](#stablesort-)
-* [`symmetricDifference`](#symmetricdifference)
-* [`symmetricDifferenceBy`](#symmetricdifferenceby)
-* [`symmetricDifferenceWith`](#symmetricdifferencewith)
-* [`tail`](#tail)
-* [`take`](#take)
-* [`takeRight`](#takeright)
-* [`takeRightWhile`](#takerightwhile)
-* [`takeWhile`](#takewhile)
-* [`toHash`](#tohash)
-* [`union`](#union)
-* [`unionBy`](#unionby)
-* [`unionWith`](#unionwith)
-* [`uniqueElements`](#uniqueelements)
-* [`uniqueElementsBy`](#uniqueelementsby)
-* [`uniqueElementsByRight`](#uniqueelementsbyright)
-* [`uniqueSymmetricDifference`](#uniquesymmetricdifference)
-* [`unzip`](#unzip)
-* [`unzipWith`](#unzipwith-)
-* [`without`](#without)
-* [`xProd`](#xprod)
-* [`zip`](#zip)
-* [`zipObject`](#zipobject)
-* [`zipWith`](#zipwith-)
-
-View contents
-
-* [`arrayToHtmlList`](#arraytohtmllist)
-* [`bottomVisible`](#bottomvisible)
-* [`copyToClipboard`](#copytoclipboard-)
-* [`counter`](#counter-)
-* [`createElement`](#createelement)
-* [`createEventHub`](#createeventhub-)
-* [`currentURL`](#currenturl)
-* [`detectDeviceType`](#detectdevicetype)
-* [`elementContains`](#elementcontains)
-* [`elementIsVisibleInViewport`](#elementisvisibleinviewport-)
-* [`formToObject`](#formtoobject)
-* [`getImages`](#getimages)
-* [`getScrollPosition`](#getscrollposition)
-* [`getStyle`](#getstyle)
-* [`hasClass`](#hasclass)
-* [`hashBrowser`](#hashbrowser-)
-* [`hide`](#hide)
-* [`httpsRedirect`](#httpsredirect)
-* [`insertAfter`](#insertafter)
-* [`insertBefore`](#insertbefore)
-* [`isBrowserTabFocused`](#isbrowsertabfocused)
-* [`nodeListToArray`](#nodelisttoarray)
-* [`observeMutations`](#observemutations-)
-* [`off`](#off)
-* [`on`](#on)
-* [`onUserInputChange`](#onuserinputchange-)
-* [`prefix`](#prefix)
-* [`recordAnimationFrames`](#recordanimationframes)
-* [`redirect`](#redirect)
-* [`runAsync`](#runasync-)
-* [`scrollToTop`](#scrolltotop)
-* [`serializeForm`](#serializeform)
-* [`setStyle`](#setstyle)
-* [`show`](#show)
-* [`smoothScroll`](#smoothscroll)
-* [`toggleClass`](#toggleclass)
-* [`triggerEvent`](#triggerevent)
-* [`UUIDGeneratorBrowser`](#uuidgeneratorbrowser)
-
-View contents
-
-* [`dayOfYear`](#dayofyear)
-* [`formatDuration`](#formatduration)
-* [`getColonTimeFromDate`](#getcolontimefromdate)
-* [`getDaysDiffBetweenDates`](#getdaysdiffbetweendates)
-* [`getMeridiemSuffixOfInteger`](#getmeridiemsuffixofinteger)
-* [`isAfterDate`](#isafterdate)
-* [`isBeforeDate`](#isbeforedate)
-* [`isSameDate`](#issamedate)
-* [`isWeekday`](#isweekday)
-* [`isWeekend`](#isweekend)
-* [`maxDate`](#maxdate)
-* [`minDate`](#mindate)
-* [`tomorrow`](#tomorrow)
-* [`yesterday`](#yesterday)
-
-View contents
-
-* [`attempt`](#attempt)
-* [`bind`](#bind)
-* [`bindKey`](#bindkey)
-* [`chainAsync`](#chainasync)
-* [`checkProp`](#checkprop)
-* [`compose`](#compose)
-* [`composeRight`](#composeright)
-* [`converge`](#converge)
-* [`curry`](#curry)
-* [`debounce`](#debounce)
-* [`defer`](#defer)
-* [`delay`](#delay)
-* [`functionName`](#functionname)
-* [`hz`](#hz)
-* [`memoize`](#memoize-)
-* [`negate`](#negate)
-* [`once`](#once)
-* [`partial`](#partial)
-* [`partialRight`](#partialright)
-* [`runPromisesInSeries`](#runpromisesinseries)
-* [`sleep`](#sleep)
-* [`throttle`](#throttle-)
-* [`times`](#times)
-* [`uncurry`](#uncurry)
-* [`unfold`](#unfold)
-* [`when`](#when)
-
-View contents
-
-* [`approximatelyEqual`](#approximatelyequal)
-* [`average`](#average)
-* [`averageBy`](#averageby)
-* [`binomialCoefficient`](#binomialcoefficient)
-* [`clampNumber`](#clampnumber)
-* [`degreesToRads`](#degreestorads)
-* [`digitize`](#digitize)
-* [`distance`](#distance)
-* [`elo`](#elo-)
-* [`factorial`](#factorial)
-* [`fibonacci`](#fibonacci)
-* [`gcd`](#gcd)
-* [`geometricProgression`](#geometricprogression)
-* [`hammingDistance`](#hammingdistance)
-* [`inRange`](#inrange)
-* [`isDivisible`](#isdivisible)
-* [`isEven`](#iseven)
-* [`isNegativeZero`](#isnegativezero)
-* [`isOdd`](#isodd)
-* [`isPrime`](#isprime)
-* [`lcm`](#lcm)
-* [`luhnCheck`](#luhncheck-)
-* [`mapNumRange`](#mapnumrange)
-* [`maxBy`](#maxby)
-* [`median`](#median)
-* [`midpoint`](#midpoint)
-* [`minBy`](#minby)
-* [`percentile`](#percentile)
-* [`powerset`](#powerset)
-* [`primes`](#primes)
-* [`radsToDegrees`](#radstodegrees)
-* [`randomIntArrayInRange`](#randomintarrayinrange)
-* [`randomIntegerInRange`](#randomintegerinrange)
-* [`randomNumberInRange`](#randomnumberinrange)
-* [`round`](#round)
-* [`sdbm`](#sdbm)
-* [`standardDeviation`](#standarddeviation)
-* [`sum`](#sum)
-* [`sumBy`](#sumby)
-* [`sumPower`](#sumpower)
-* [`toSafeInteger`](#tosafeinteger)
-* [`vectorDistance`](#vectordistance)
-
-View contents
-
-* [`atob`](#atob)
-* [`btoa`](#btoa)
-* [`colorize`](#colorize)
-* [`createDirIfNotExists`](#createdirifnotexists)
-* [`hasFlags`](#hasflags)
-* [`hashNode`](#hashnode)
-* [`isDuplexStream`](#isduplexstream)
-* [`isReadableStream`](#isreadablestream)
-* [`isStream`](#isstream)
-* [`isTravisCI`](#istravisci)
-* [`isWritableStream`](#iswritablestream)
-* [`JSONToFile`](#jsontofile)
-* [`readFileLines`](#readfilelines)
-* [`untildify`](#untildify)
-* [`UUIDGeneratorNode`](#uuidgeneratornode)
-
-View contents
-
-* [`bindAll`](#bindall)
-* [`deepClone`](#deepclone)
-* [`deepFreeze`](#deepfreeze)
-* [`deepGet`](#deepget)
-* [`deepMapKeys`](#deepmapkeys-)
-* [`defaults`](#defaults)
-* [`dig`](#dig)
-* [`equals`](#equals-)
-* [`findKey`](#findkey)
-* [`findLastKey`](#findlastkey)
-* [`flattenObject`](#flattenobject)
-* [`forOwn`](#forown)
-* [`forOwnRight`](#forownright)
-* [`functions`](#functions)
-* [`get`](#get)
-* [`hasKey`](#haskey)
-* [`invertKeyValues`](#invertkeyvalues)
-* [`lowercaseKeys`](#lowercasekeys)
-* [`mapKeys`](#mapkeys)
-* [`mapValues`](#mapvalues)
-* [`matches`](#matches)
-* [`matchesWith`](#matcheswith)
-* [`merge`](#merge)
-* [`nest`](#nest)
-* [`objectFromPairs`](#objectfrompairs)
-* [`objectToPairs`](#objecttopairs)
-* [`omit`](#omit)
-* [`omitBy`](#omitby)
-* [`orderBy`](#orderby)
-* [`pick`](#pick)
-* [`pickBy`](#pickby)
-* [`renameKeys`](#renamekeys)
-* [`shallowClone`](#shallowclone)
-* [`size`](#size)
-* [`transform`](#transform)
-* [`truthCheckCollection`](#truthcheckcollection)
-* [`unflattenObject`](#unflattenobject-)
-
-View contents
-
-* [`byteSize`](#bytesize)
-* [`capitalize`](#capitalize)
-* [`capitalizeEveryWord`](#capitalizeeveryword)
-* [`compactWhitespace`](#compactwhitespace)
-* [`CSVToArray`](#csvtoarray)
-* [`CSVToJSON`](#csvtojson-)
-* [`decapitalize`](#decapitalize)
-* [`escapeHTML`](#escapehtml)
-* [`escapeRegExp`](#escaperegexp)
-* [`fromCamelCase`](#fromcamelcase)
-* [`indentString`](#indentstring)
-* [`isAbsoluteURL`](#isabsoluteurl)
-* [`isAnagram`](#isanagram)
-* [`isLowerCase`](#islowercase)
-* [`isUpperCase`](#isuppercase)
-* [`mapString`](#mapstring)
-* [`mask`](#mask)
-* [`pad`](#pad)
-* [`palindrome`](#palindrome)
-* [`pluralize`](#pluralize)
-* [`removeNonASCII`](#removenonascii)
-* [`reverseString`](#reversestring)
-* [`sortCharactersInString`](#sortcharactersinstring)
-* [`splitLines`](#splitlines)
-* [`stringPermutations`](#stringpermutations-)
-* [`stripHTMLTags`](#striphtmltags)
-* [`toCamelCase`](#tocamelcase)
-* [`toKebabCase`](#tokebabcase)
-* [`toSnakeCase`](#tosnakecase)
-* [`toTitleCase`](#totitlecase)
-* [`truncateString`](#truncatestring)
-* [`unescapeHTML`](#unescapehtml)
-* [`URLJoin`](#urljoin-)
-* [`words`](#words)
-
-View contents
-
-* [`getType`](#gettype)
-* [`is`](#is)
-* [`isArrayLike`](#isarraylike)
-* [`isBoolean`](#isboolean)
-* [`isEmpty`](#isempty)
-* [`isFunction`](#isfunction)
-* [`isNil`](#isnil)
-* [`isNull`](#isnull)
-* [`isNumber`](#isnumber)
-* [`isObject`](#isobject)
-* [`isObjectLike`](#isobjectlike)
-* [`isPlainObject`](#isplainobject)
-* [`isPrimitive`](#isprimitive)
-* [`isPromiseLike`](#ispromiselike)
-* [`isString`](#isstring)
-* [`isSymbol`](#issymbol)
-* [`isUndefined`](#isundefined)
-* [`isValidJSON`](#isvalidjson)
-
-View contents
-
-* [`castArray`](#castarray)
-* [`cloneRegExp`](#cloneregexp)
-* [`coalesce`](#coalesce)
-* [`coalesceFactory`](#coalescefactory)
-* [`extendHex`](#extendhex)
-* [`getURLParameters`](#geturlparameters)
-* [`hexToRGB`](#hextorgb-)
-* [`httpGet`](#httpget)
-* [`httpPost`](#httppost)
-* [`isBrowser`](#isbrowser)
-* [`mostPerformant`](#mostperformant)
-* [`nthArg`](#ntharg)
-* [`objectToQueryString`](#objecttoquerystring)
-* [`parseCookie`](#parsecookie)
-* [`prettyBytes`](#prettybytes-)
-* [`randomHexColorCode`](#randomhexcolorcode)
-* [`RGBToHex`](#rgbtohex)
-* [`serializeCookie`](#serializecookie)
-* [`timeTaken`](#timetaken)
-* [`toCurrency`](#tocurrency)
-* [`toDecimalMark`](#todecimalmark)
-* [`toOrdinalSuffix`](#toordinalsuffix)
-* [`validateNumber`](#validatenumber)
-* [`yesNo`](#yesno)
-
-Examples
-
-```js
-const firstTwoMax = ary(Math.max, 2);
-[[2, 6, 'a'], [6, 4, 8], [10]].map(x => firstTwoMax(...x)); // [6, 6, 10]
-```
-
[⬆ Back to top](#contents)
-
-### call
-
-Given a key and a set of arguments, call them when given a context. Primarily useful in composition.
-
-Use a closure to call a stored key with stored arguments.
-
-```js
-const call = (key, ...args) => context => context[key](...args);
-```
-
-Examples
-
-```js
-Promise.resolve([1, 2, 3])
- .then(call('map', x => 2 * x))
- .then(console.log); // [ 2, 4, 6 ]
-const map = call.bind(null, 'map');
-Promise.resolve([1, 2, 3])
- .then(map(x => 2 * x))
- .then(console.log); // [ 2, 4, 6 ]
-```
-
[⬆ Back to top](#contents)
-
-### collectInto
-
-Changes a function that accepts an array into a variadic function.
-
-Given a function, return a closure that collects all inputs into an array-accepting function.
-
-```js
-const collectInto = fn => (...args) => fn(args);
-```
-
-Examples
-
-```js
-const Pall = collectInto(Promise.all.bind(Promise));
-let p1 = Promise.resolve(1);
-let p2 = Promise.resolve(2);
-let p3 = new Promise(resolve => setTimeout(resolve, 2000, 3));
-Pall(p1, p2, p3).then(console.log); // [1, 2, 3] (after about 2 seconds)
-```
-
[⬆ Back to top](#contents)
-
-### flip
-
-Flip takes a function as an argument, then makes the first argument the last.
-
-Return a closure that takes variadic inputs, and splices the last argument to make it the first argument before applying the rest.
-
-```js
-const flip = fn => (first, ...rest) => fn(...rest, first);
-```
-
-Examples
-
-```js
-let a = { name: 'John Smith' };
-let b = {};
-const mergeFrom = flip(Object.assign);
-let mergePerson = mergeFrom.bind(null, a);
-mergePerson(b); // == b
-b = {};
-Object.assign(b, a); // == b
-```
-
[⬆ Back to top](#contents)
-
-### over
-
-Creates a function that invokes each provided function with the arguments it receives and returns the results.
-
-Use `Array.prototype.map()` and `Function.prototype.apply()` to apply each function to the given arguments.
-
-```js
-const over = (...fns) => (...args) => fns.map(fn => fn.apply(null, args));
-```
-
-Examples
-
-```js
-const minMax = over(Math.min, Math.max);
-minMax(1, 2, 3, 4, 5); // [1,5]
-```
-
[⬆ Back to top](#contents)
-
-### overArgs
-
-Creates a function that invokes the provided function with its arguments transformed.
-
-Use `Array.prototype.map()` to apply `transforms` to `args` in combination with the spread operator (`...`) to pass the transformed arguments to `fn`.
-
-```js
-const overArgs = (fn, transforms) => (...args) => fn(...args.map((val, i) => transforms[i](val)));
-```
-
-Examples
-
-```js
-const square = n => n * n;
-const double = n => n * 2;
-const fn = overArgs((x, y) => [x, y], [square, double]);
-fn(9, 3); // [81, 6]
-```
-
[⬆ Back to top](#contents)
-
-### pipeAsyncFunctions
-
-Performs left-to-right function composition for asynchronous functions.
-
-Use `Array.prototype.reduce()` with the spread operator (`...`) to perform left-to-right function composition using `Promise.then()`.
-The functions can return a combination of: simple values, `Promise`'s, or they can be defined as `async` ones returning through `await`.
-All functions must be unary.
-
-```js
-const pipeAsyncFunctions = (...fns) => arg => fns.reduce((p, f) => p.then(f), Promise.resolve(arg));
-```
-
-Examples
-
-```js
-const sum = pipeAsyncFunctions(
- x => x + 1,
- x => new Promise(resolve => setTimeout(() => resolve(x + 2), 1000)),
- x => x + 3,
- async x => (await x) + 4
-);
-(async() => {
- console.log(await sum(5)); // 15 (after one second)
-})();
-```
-
[⬆ Back to top](#contents)
-
-### pipeFunctions
-
-Performs left-to-right function composition.
-
-Use `Array.prototype.reduce()` with the spread operator (`...`) 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 pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
-```
-
-Examples
-
-```js
-const add5 = x => x + 5;
-const multiply = (x, y) => x * y;
-const multiplyAndAdd5 = pipeFunctions(multiply, add5);
-multiplyAndAdd5(5, 2); // 15
-```
-
[⬆ Back to top](#contents)
-
-### promisify
-
-Converts an asynchronous function to return a promise.
-
-*In Node 8+, you can use [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original)*
-
-Use currying to return a function returning a `Promise` that calls the original function.
-Use the `...rest` operator to pass in all the parameters.
-
-```js
-const promisify = func => (...args) =>
- new Promise((resolve, reject) =>
- func(...args, (err, result) => (err ? reject(err) : resolve(result)))
- );
-```
-
-Examples
-
-```js
-const delay = promisify((d, cb) => setTimeout(cb, d));
-delay(2000).then(() => console.log('Hi!')); // // Promise resolves after 2s
-```
-
[⬆ Back to top](#contents)
-
-### rearg
-
-Creates a function that invokes the provided function with its arguments arranged according to the specified indexes.
-
-Use `Array.prototype.map()` to reorder arguments based on `indexes` in combination with the spread operator (`...`) to pass the transformed arguments to `fn`.
-
-```js
-const rearg = (fn, indexes) => (...args) => fn(...indexes.map(i => args[i]));
-```
-
-Examples
-
-```js
-var rearged = rearg(
- function(a, b, c) {
- return [a, b, c];
- },
- [2, 0, 1]
-);
-rearged('b', 'c', 'a'); // ['a', 'b', 'c']
-```
-
[⬆ Back to top](#contents)
-
-### spreadOver
-
-Takes a variadic function and returns a closure that accepts an array of arguments to map to the inputs of the function.
-
-Use closures and the spread operator (`...`) to map the array of arguments to the inputs of the function.
-
-```js
-const spreadOver = fn => argsArr => fn(...argsArr);
-```
-
-Examples
-
-```js
-const arrayMax = spreadOver(Math.max);
-arrayMax([1, 2, 3]); // 3
-```
-
[⬆ Back to top](#contents)
-
-### 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);
-```
-
-Examples
-
-```js
-['6', '8', '10'].map(unary(parseInt)); // [6, 8, 10]
-```
-
[⬆ Back to top](#contents)
-
----
-
-## 📚 Array
-
-
-### all
-
-Returns `true` if the provided predicate function returns `true` for all elements in a collection, `false` otherwise.
-
-Use `Array.prototype.every()` to test if all elements in the collection return `true` based on `fn`.
-Omit the second argument, `fn`, to use `Boolean` as a default.
-
-```js
-const all = (arr, fn = Boolean) => arr.every(fn);
-```
-
-Examples
-
-```js
-all([4, 2, 3], x => x > 1); // true
-all([1, 2, 3]); // true
-```
-
[⬆ Back to top](#contents)
-
-### allEqual
-
-Check if all elements in an array are equal.
-
-Use `Array.prototype.every()` to check if all the elements of the array are the same as the first one.
-Elements in the array are compared using the strict comparison operator, which does not account for `NaN` self-inequality.
-
-```js
-const allEqual = arr => arr.every(val => val === arr[0]);
-```
-
-Examples
-
-```js
-allEqual([1, 2, 3, 4, 5, 6]); // false
-allEqual([1, 1, 1, 1]); // true
-```
-
[⬆ Back to top](#contents)
-
-### any
-
-Returns `true` if the provided predicate function returns `true` for at least one element in a collection, `false` otherwise.
-
-Use `Array.prototype.some()` to test if any elements in the collection return `true` based on `fn`.
-Omit the second argument, `fn`, to use `Boolean` as a default.
-
-```js
-const any = (arr, fn = Boolean) => arr.some(fn);
-```
-
-Examples
-
-```js
-any([0, 1, 2, 0], x => x >= 2); // true
-any([0, 0, 1, 0]); // true
-```
-
[⬆ Back to top](#contents)
-
-### arrayToCSV
-
-Converts a 2D array to a comma-separated values (CSV) string.
-
-Use `Array.prototype.map()` and `Array.prototype.join(delimiter)` to combine individual 1D arrays (rows) into strings.
-Use `Array.prototype.join('\n')` to combine all rows into a CSV string, separating each row with a newline.
-Omit the second argument, `delimiter`, to use a default delimiter of `,`.
-
-```js
-const arrayToCSV = (arr, delimiter = ',') =>
- arr
- .map(v => v.map(x => (isNaN(x) ? `"${x.replace(/"/g, '""')}"` : x)).join(delimiter))
- .join('\n');
-```
-
-Examples
-
-```js
-arrayToCSV([['a', 'b'], ['c', 'd']]); // '"a","b"\n"c","d"'
-arrayToCSV([['a', 'b'], ['c', 'd']], ';'); // '"a";"b"\n"c";"d"'
-arrayToCSV([['a', '"b" great'], ['c', 3.1415]]); // '"a","""b"" great"\n"c",3.1415'
-```
-
[⬆ Back to top](#contents)
-
-### bifurcate
-
-Splits values into two groups. If an element in `filter` is truthy, the corresponding element in the collection belongs to the first group; otherwise, it belongs to the second group.
-
-Use `Array.prototype.reduce()` and `Array.prototype.push()` to add elements to groups, based on `filter`.
-
-```js
-const bifurcate = (arr, filter) =>
- arr.reduce((acc, val, i) => (acc[filter[i] ? 0 : 1].push(val), acc), [[], []]);
-```
-
-Examples
-
-```js
-bifurcate(['beep', 'boop', 'foo', 'bar'], [true, true, false, true]); // [ ['beep', 'boop', 'bar'], ['foo'] ]
-```
-
[⬆ Back to top](#contents)
-
-### bifurcateBy
-
-Splits values into two groups according to a predicate function, which specifies which group an element in the input collection belongs to. If the predicate function returns a truthy value, the collection element belongs to the first group; otherwise, it belongs to the second group.
-
-Use `Array.prototype.reduce()` and `Array.prototype.push()` to add elements to groups, based on the value returned by `fn` for each element.
-
-```js
-const bifurcateBy = (arr, fn) =>
- arr.reduce((acc, val, i) => (acc[fn(val, i) ? 0 : 1].push(val), acc), [[], []]);
-```
-
-Examples
-
-```js
-bifurcateBy(['beep', 'boop', 'foo', 'bar'], x => x[0] === 'b'); // [ ['beep', 'boop', 'bar'], ['foo'] ]
-```
-
[⬆ Back to top](#contents)
-
-### chunk
-
-Chunks an array into smaller arrays of a specified size.
-
-Use `Array.from()` to create a new array, that fits the number of chunks that will be produced.
-Use `Array.prototype.slice()` to map each element of the new array to a chunk the length of `size`.
-If the original array can't be split evenly, the final chunk will contain the remaining elements.
-
-```js
-const chunk = (arr, size) =>
- Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
- arr.slice(i * size, i * size + size)
- );
-```
-
-Examples
-
-```js
-chunk([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]]
-```
-
[⬆ Back to top](#contents)
-
-### compact
-
-Removes falsy values from an array.
-
-Use `Array.prototype.filter()` to filter out falsy values (`false`, `null`, `0`, `""`, `undefined`, and `NaN`).
-
-```js
-const compact = arr => arr.filter(Boolean);
-```
-
-Examples
-
-```js
-compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]); // [ 1, 2, 3, 'a', 's', 34 ]
-```
-
[⬆ Back to top](#contents)
-
-### countBy
-
-Groups the elements of an array based on the given function and returns the count of elements in each group.
-
-Use `Array.prototype.map()` to map the values of an array to a function or property name.
-Use `Array.prototype.reduce()` to create an object, where the keys are produced from the mapped results.
-
-```js
-const countBy = (arr, fn) =>
- arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => {
- acc[val] = (acc[val] || 0) + 1;
- return acc;
- }, {});
-```
-
-Examples
-
-```js
-countBy([6.1, 4.2, 6.3], Math.floor); // {4: 1, 6: 2}
-countBy(['one', 'two', 'three'], 'length'); // {3: 2, 5: 1}
-```
-
[⬆ Back to top](#contents)
-
-### countOccurrences
-
-Counts the occurrences of a value in an array.
-
-Use `Array.prototype.reduce()` to increment a counter each time you encounter the specific value inside the array.
-
-```js
-const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a), 0);
-```
-
-Examples
-
-```js
-countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3
-```
-
[⬆ Back to top](#contents)
-
-### deepFlatten
-
-Deep flattens an array.
-
-Use recursion.
-Use `Array.prototype.concat()` with an empty array (`[]`) and the spread operator (`...`) to flatten an array.
-Recursively flatten each element that is an array.
-
-```js
-const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));
-```
-
-Examples
-
-```js
-deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5]
-```
-
[⬆ Back to top](#contents)
-
-### difference
-
-Returns the difference between two arrays.
-
-Create a `Set` from `b`, then use `Array.prototype.filter()` on `a` to only keep values not contained in `b`.
-
-```js
-const difference = (a, b) => {
- const s = new Set(b);
- return a.filter(x => !s.has(x));
-};
-```
-
-Examples
-
-```js
-difference([1, 2, 3], [1, 2, 4]); // [3]
-```
-
[⬆ Back to top](#contents)
-
-### 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.prototype.map()` to apply `fn` to each element in `a`, then `Array.prototype.filter()`
-
-```js
-const differenceBy = (a, b, fn) => {
- const s = new Set(b.map(fn));
- return a.map(fn).filter(el => !s.has(el));
-};
-```
-
-Examples
-
-```js
-differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [1]
-differenceBy([{ x: 2 }, { x: 1 }], [{ x: 1 }], v => v.x); // [2]
-```
-
[⬆ Back to top](#contents)
-
-### differenceWith
-
-Filters out all values from an array for which the comparator function does not return `true`.
-
-Use `Array.prototype.filter()` and `Array.prototype.findIndex()` to find the appropriate values.
-
-```js
-const differenceWith = (arr, val, comp) => arr.filter(a => val.findIndex(b => comp(a, b)) === -1);
-```
-
-Examples
-
-```js
-differenceWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0], (a, b) => Math.round(a) === Math.round(b)); // [1, 1.2]
-```
-
[⬆ Back to top](#contents)
-
-### drop
-
-Returns a new array with `n` elements removed from the left.
-
-Use `Array.prototype.slice()` to remove the specified number of elements from the left.
-
-```js
-const drop = (arr, n = 1) => arr.slice(n);
-```
-
-Examples
-
-```js
-drop([1, 2, 3]); // [2,3]
-drop([1, 2, 3], 2); // [3]
-drop([1, 2, 3], 42); // []
-```
-
[⬆ Back to top](#contents)
-
-### dropRight
-
-Returns a new array with `n` elements removed from the right.
-
-Use `Array.prototype.slice()` to remove the specified number of elements from the right.
-
-```js
-const dropRight = (arr, n = 1) => arr.slice(0, -n);
-```
-
-Examples
-
-```js
-dropRight([1, 2, 3]); // [1,2]
-dropRight([1, 2, 3], 2); // [1]
-dropRight([1, 2, 3], 42); // []
-```
-
[⬆ Back to top](#contents)
-
-### dropRightWhile
-
-Removes elements from the end of an array until the passed function returns `true`. Returns the remaining elements in the array.
-
-Loop through the array, using `Array.prototype.slice()` to drop the last element of the array until the returned value from the function is `true`.
-Returns the remaining elements.
-
-```js
-const dropRightWhile = (arr, func) => {
- let rightIndex = arr.length;
- while (rightIndex-- && !func(arr[rightIndex]));
- return arr.slice(0, rightIndex + 1);
-};
-```
-
-Examples
-
-```js
-dropRightWhile([1, 2, 3, 4], n => n < 3); // [1, 2]
-```
-
[⬆ Back to top](#contents)
-
-### dropWhile
-
-Removes elements in an array until the passed function returns `true`. Returns the remaining elements in the array.
-
-Loop through the array, using `Array.prototype.slice()` to drop the first element of the array until the returned value from the function is `true`.
-Returns the remaining elements.
-
-```js
-const dropWhile = (arr, func) => {
- while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1);
- return arr;
-};
-```
-
-Examples
-
-```js
-dropWhile([1, 2, 3, 4], n => n >= 3); // [3,4]
-```
-
[⬆ Back to top](#contents)
-
-### everyNth
-
-Returns every nth element in an array.
-
-Use `Array.prototype.filter()` to create a new array that contains every nth element of a given array.
-
-```js
-const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1);
-```
-
-Examples
-
-```js
-everyNth([1, 2, 3, 4, 5, 6], 2); // [ 2, 4, 6 ]
-```
-
[⬆ Back to top](#contents)
-
-### filterFalsy
-
-Filters out the falsy values in an array.
-
-Use `Array.prototype.filter()` to get an array containing only truthy values.
-
-```js
-const filterFalsy = arr => arr.filter(Boolean);
-```
-
-Examples
-
-```js
-filterFalsy(['', true, {}, false, 'sample', 1, 0]); // [true, {}, 'sample', 1]
-```
-
[⬆ Back to top](#contents)
-
-### filterNonUnique
-
-Filters out the non-unique values in an array.
-
-Use `Array.prototype.filter()` for an array containing only the unique values.
-
-```js
-const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
-```
-
-Examples
-
-```js
-filterNonUnique([1, 2, 2, 3, 4, 4, 5]); // [1, 3, 5]
-```
-
[⬆ Back to top](#contents)
-
-### filterNonUniqueBy
-
-Filters out the non-unique values in an array, based on a provided comparator function.
-
-Use `Array.prototype.filter()` and `Array.prototype.every()` for an array containing only the unique values, based on the comparator function, `fn`.
-The comparator function takes four arguments: the values of the two elements being compared and their indexes.
-
-```js
-const filterNonUniqueBy = (arr, fn) =>
- arr.filter((v, i) => arr.every((x, j) => (i === j) === fn(v, x, i, j)));
-```
-
-Examples
-
-```js
-filterNonUniqueBy(
- [
- { id: 0, value: 'a' },
- { id: 1, value: 'b' },
- { id: 2, value: 'c' },
- { id: 1, value: 'd' },
- { id: 0, value: 'e' }
- ],
- (a, b) => a.id == b.id
-); // [ { id: 2, value: 'c' } ]
-```
-
[⬆ Back to top](#contents)
-
-### findLast
-
-Returns the last element for which the provided function returns a truthy value.
-
-Use `Array.prototype.filter()` to remove elements for which `fn` returns falsy values, `Array.prototype.pop()` to get the last one.
-
-```js
-const findLast = (arr, fn) => arr.filter(fn).pop();
-```
-
-Examples
-
-```js
-findLast([1, 2, 3, 4], n => n % 2 === 1); // 3
-```
-
[⬆ Back to top](#contents)
-
-### findLastIndex
-
-Returns the index of the last element for which the provided function returns a truthy value.
-
-Use `Array.prototype.map()` to map each element to an array with its index and value.
-Use `Array.prototype.filter()` to remove elements for which `fn` returns falsy values, `Array.prototype.pop()` to get the last one.
-`-1` is the default value when not found.
-
-```js
-const findLastIndex = (arr, fn) =>
- (arr
- .map((val, i) => [i, val])
- .filter(([i, val]) => fn(val, i, arr))
- .pop() || [-1])[0];
-```
-
-Examples
-
-```js
-findLastIndex([1, 2, 3, 4], n => n % 2 === 1); // 2 (index of the value 3)
-findLastIndex([1, 2, 3, 4], n => n === 5); // -1 (default value when not found)
-```
-
[⬆ Back to top](#contents)
-
-### flatten
-
-Flattens an array up to the specified depth.
-
-Use recursion, decrementing `depth` by 1 for each level of depth.
-Use `Array.prototype.reduce()` and `Array.prototype.concat()` to merge elements or arrays.
-Base case, for `depth` equal to `1` stops recursion.
-Omit the second argument, `depth` to flatten only to a depth of `1` (single flatten).
-
-```js
-const flatten = (arr, depth = 1) =>
- arr.reduce((a, v) => a.concat(depth > 1 && Array.isArray(v) ? flatten(v, depth - 1) : v), []);
-```
-
-Examples
-
-```js
-flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
-flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]
-```
-
[⬆ Back to top](#contents)
-
-### forEachRight
-
-Executes a provided function once for each array element, starting from the array's last element.
-
-Use `Array.prototype.slice(0)` to clone the given array, `Array.prototype.reverse()` to reverse it and `Array.prototype.forEach()` to iterate over the reversed array.
-
-```js
-const forEachRight = (arr, callback) =>
- arr
- .slice(0)
- .reverse()
- .forEach(callback);
-```
-
-Examples
-
-```js
-forEachRight([1, 2, 3, 4], val => console.log(val)); // '4', '3', '2', '1'
-```
-
[⬆ Back to top](#contents)
-
-### groupBy
-
-Groups the elements of an array based on the given function.
-
-Use `Array.prototype.map()` to map the values of an array to a function or property name.
-Use `Array.prototype.reduce()` to create an object, where the keys are produced from the mapped results.
-
-```js
-const groupBy = (arr, fn) =>
- arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val, i) => {
- acc[val] = (acc[val] || []).concat(arr[i]);
- return acc;
- }, {});
-```
-
-Examples
-
-```js
-groupBy([6.1, 4.2, 6.3], Math.floor); // {4: [4.2], 6: [6.1, 6.3]}
-groupBy(['one', 'two', 'three'], 'length'); // {3: ['one', 'two'], 5: ['three']}
-```
-
[⬆ Back to top](#contents)
-
-### head
-
-Returns the head of a list.
-
-Use `arr[0]` to return the first element of the passed array.
-
-```js
-const head = arr => arr[0];
-```
-
-Examples
-
-```js
-head([1, 2, 3]); // 1
-```
-
[⬆ Back to top](#contents)
-
-### includesAll
-
-Returns `true` if all the elements ιν `values` are included in `arr`, `false` otherwise.
-
-Use `Array.prototype.every()` and `Array.prototype.includes()` to check if all elements of `values` are included in `arr`.
-
-```js
-const includesAll = (arr, values) => values.every(v => arr.includes(v));
-```
-
-Examples
-
-```js
-includesAll([1, 2, 3, 4], [1, 4]); // true
-includesAll([1, 2, 3, 4], [1, 5]); // false
-```
-
[⬆ Back to top](#contents)
-
-### includesAny
-
-Returns `true` if at least one element of values is included in arr , `false` otherwise.
-
-Use `Array.prototype.some()` and `Array.prototype.includes()` to check if at least one element of `values` is included in `arr`.
-
-```js
-const includesAny = (arr, values) => values.some(v => arr.includes(v));
-```
-
-Examples
-
-```js
-includesAny([1, 2, 3, 4], [2, 9]); // true
-includesAny([1, 2, 3, 4], [8, 9]); // false
-```
-
[⬆ Back to top](#contents)
-
-### indexOfAll
-
-Returns all indices of `val` in an array.
-If `val` never occurs, returns `[]`.
-
-Use `Array.prototype.reduce()` to loop over elements and store indices for matching elements.
-Return the array of indices.
-
-```js
-const indexOfAll = (arr, val) => arr.reduce((acc, el, i) => (el === val ? [...acc, i] : acc), []);
-```
-
-Examples
-
-```js
-indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
-indexOfAll([1, 2, 3], 4); // []
-```
-
[⬆ Back to top](#contents)
-
-### initial
-
-Returns all the elements of an array except the last one.
-
-Use `arr.slice(0,-1)` to return all but the last element of the array.
-
-```js
-const initial = arr => arr.slice(0, -1);
-```
-
-Examples
-
-```js
-initial([1, 2, 3]); // [1,2]
-```
-
[⬆ Back to top](#contents)
-
-### initialize2DArray
-
-Initializes a 2D array of given width and height and value.
-
-Use `Array.prototype.map()` to generate h rows where each is a new array of size w initialize with value. If the value is not provided, default to `null`.
-
-```js
-const initialize2DArray = (w, h, val = null) =>
- Array.from({ length: h }).map(() => Array.from({ length: w }).fill(val));
-```
-
-Examples
-
-```js
-initialize2DArray(2, 2, 0); // [[0,0], [0,0]]
-```
-
[⬆ Back to top](#contents)
-
-### initializeArrayWithRange
-
-Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive with their common difference `step`.
-
-Use `Array.from()` to create an array of the desired length, `(end - start + 1)/step`, and a map function to fill it with the desired values in the given range.
-You can omit `start` to use a default value of `0`.
-You can omit `step` to use a default value of `1`.
-
-```js
-const initializeArrayWithRange = (end, start = 0, step = 1) =>
- Array.from({ length: Math.ceil((end - start + 1) / step) }, (v, i) => i * step + start);
-```
-
-Examples
-
-```js
-initializeArrayWithRange(5); // [0,1,2,3,4,5]
-initializeArrayWithRange(7, 3); // [3,4,5,6,7]
-initializeArrayWithRange(9, 0, 2); // [0,2,4,6,8]
-```
-
[⬆ Back to top](#contents)
-
-### initializeArrayWithRangeRight
-
-Initializes an array containing the numbers in the specified range (in reverse) where `start` and `end` are inclusive with their common difference `step`.
-
-Use `Array.from(Math.ceil((end+1-start)/step))` to create an array of the desired length(the amounts of elements is equal to `(end-start)/step` or `(end+1-start)/step` for inclusive end), `Array.prototype.map()` to fill with the desired values in a range.
-You can omit `start` to use a default value of `0`.
-You can omit `step` to use a default value of `1`.
-
-```js
-const initializeArrayWithRangeRight = (end, start = 0, step = 1) =>
- Array.from({ length: Math.ceil((end + 1 - start) / step) }).map(
- (v, i, arr) => (arr.length - i - 1) * step + start
- );
-```
-
-Examples
-
-```js
-initializeArrayWithRangeRight(5); // [5,4,3,2,1,0]
-initializeArrayWithRangeRight(7, 3); // [7,6,5,4,3]
-initializeArrayWithRangeRight(9, 0, 2); // [8,6,4,2,0]
-```
-
[⬆ Back to top](#contents)
-
-### initializeArrayWithValues
-
-Initializes and fills an array with the specified values.
-
-Use `Array(n)` to create an array of the desired length, `fill(v)` to fill it with the desired values.
-You can omit `val` to use a default value of `0`.
-
-```js
-const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val);
-```
-
-Examples
-
-```js
-initializeArrayWithValues(5, 2); // [2, 2, 2, 2, 2]
-```
-
[⬆ Back to top](#contents)
-
-### initializeNDArray
-
-Create a n-dimensional array with given value.
-
-Use recursion.
-Use `Array.prototype.map()` to generate rows where each is a new array initialized using `initializeNDArray`.
-
-```js
-const initializeNDArray = (val, ...args) =>
- args.length === 0
- ? val
- : Array.from({ length: args[0] }).map(() => initializeNDArray(val, ...args.slice(1)));
-```
-
-Examples
-
-```js
-initializeNDArray(1, 3); // [1,1,1]
-initializeNDArray(5, 2, 2, 2); // [[[5,5],[5,5]],[[5,5],[5,5]]]
-```
-
[⬆ Back to top](#contents)
-
-### intersection
-
-Returns a list of elements that exist in both arrays.
-
-Create a `Set` from `b`, then use `Array.prototype.filter()` on `a` to only keep values contained in `b`.
-
-```js
-const intersection = (a, b) => {
- const s = new Set(b);
- return a.filter(x => s.has(x));
-};
-```
-
-Examples
-
-```js
-intersection([1, 2, 3], [4, 3, 2]); // [2, 3]
-```
-
[⬆ Back to top](#contents)
-
-### 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.prototype.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(fn));
- return a.filter(x => s.has(fn(x)));
-};
-```
-
-Examples
-
-```js
-intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [2.1]
-```
-
[⬆ Back to top](#contents)
-
-### intersectionWith
-
-Returns a list of elements that exist in both arrays, using a provided comparator function.
-
-Use `Array.prototype.filter()` and `Array.prototype.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);
-```
-
-Examples
-
-```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]
-```
-
[⬆ Back to top](#contents)
-
-### isSorted
-
-Returns `1` if the array is sorted in ascending order, `-1` if it is sorted in descending order or `0` if it is not sorted.
-
-Calculate the ordering `direction` for the first two elements.
-Use `Object.entries()` to loop over array objects and compare them in pairs.
-Return `0` if the `direction` changes or the `direction` if the last element is reached.
-
-```js
-const isSorted = arr => {
- let direction = -(arr[0] - arr[1]);
- for (let [i, val] of arr.entries()) {
- direction = !direction ? -(arr[i - 1] - arr[i]) : direction;
- if (i === arr.length - 1) return !direction ? 0 : direction;
- else if ((val - arr[i + 1]) * direction > 0) return 0;
- }
-};
-```
-
-Examples
-
-```js
-isSorted([0, 1, 2, 2]); // 1
-isSorted([4, 3, 2]); // -1
-isSorted([4, 3, 5]); // 0
-```
-
[⬆ Back to top](#contents)
-
-### join
-
-Joins all elements of an array into a string and returns this string.
-Uses a separator and an end separator.
-
-Use `Array.prototype.reduce()` to combine elements into a string.
-Omit the second argument, `separator`, to use a default separator of `','`.
-Omit the third argument, `end`, to use the same value as `separator` by default.
-
-```js
-const join = (arr, separator = ',', end = separator) =>
- arr.reduce(
- (acc, val, i) =>
- i === arr.length - 2
- ? acc + val + end
- : i === arr.length - 1
- ? acc + val
- : acc + val + separator,
- ''
- );
-```
-
-Examples
-
-```js
-join(['pen', 'pineapple', 'apple', 'pen'], ',', '&'); // "pen,pineapple,apple&pen"
-join(['pen', 'pineapple', 'apple', 'pen'], ','); // "pen,pineapple,apple,pen"
-join(['pen', 'pineapple', 'apple', 'pen']); // "pen,pineapple,apple,pen"
-```
-
[⬆ Back to top](#contents)
-
-### JSONtoCSV 
-
-Converts an array of objects to a comma-separated values (CSV) string that contains only the `columns` specified.
-
-Use `Array.prototype.join(delimiter)` to combine all the names in `columns` to create the first row.
-Use `Array.prototype.map()` and `Array.prototype.reduce()` to create a row for each object, substituting non-existent values with empty strings and only mapping values in `columns`.
-Use `Array.prototype.join('\n')` to combine all rows into a string.
-Omit the third argument, `delimiter`, to use a default delimiter of `,`.
-
-```js
-const JSONtoCSV = (arr, columns, delimiter = ',') =>
- [
- columns.join(delimiter),
- ...arr.map(obj =>
- columns.reduce(
- (acc, key) => `${acc}${!acc.length ? '' : delimiter}"${!obj[key] ? '' : obj[key]}"`,
- ''
- )
- )
- ].join('\n');
-```
-
-Examples
-
-```js
-JSONtoCSV([{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }], ['a', 'b']); // 'a,b\n"1","2"\n"3","4"\n"6",""\n"","7"'
-JSONtoCSV([{ a: 1, b: 2 }, { a: 3, b: 4, c: 5 }, { a: 6 }, { b: 7 }], ['a', 'b'], ';'); // 'a;b\n"1";"2"\n"3";"4"\n"6";""\n"";"7"'
-```
-
[⬆ Back to top](#contents)
-
-### last
-
-Returns the last element in an array.
-
-Use `arr.length - 1` to compute the index of the last element of the given array and returning it.
-
-```js
-const last = arr => arr[arr.length - 1];
-```
-
-Examples
-
-```js
-last([1, 2, 3]); // 3
-```
-
[⬆ Back to top](#contents)
-
-### longestItem
-
-Takes any number of iterable objects or objects with a `length` property and returns the longest one.
-If multiple objects have the same length, the first one will be returned.
-Returns `undefined` if no arguments are provided.
-
-Use `Array.prototype.reduce()`, comparing the `length` of objects to find the longest one.
-
-```js
-const longestItem = (...vals) => vals.reduce((a, x) => (x.length > a.length ? x : a));
-```
-
-Examples
-
-```js
-longestItem('this', 'is', 'a', 'testcase'); // 'testcase'
-longestItem(...['a', 'ab', 'abc']); // 'abc'
-longestItem(...['a', 'ab', 'abc'], 'abcd'); // 'abcd'
-longestItem([1, 2, 3], [1, 2], [1, 2, 3, 4, 5]); // [1, 2, 3, 4, 5]
-longestItem([1, 2, 3], 'foobar'); // 'foobar'
-```
-
[⬆ Back to top](#contents)
-
-### mapObject 
-
-Maps the values of an array to an object using a function, where the key-value pairs consist of the stringified value as the key and the mapped value.
-
-Use an anonymous inner function scope to declare an undefined memory space, using closures to store a return value. Use a new `Array` to store the array with a map of the function over its data set and a comma operator to return a second step, without needing to move from one context to another (due to closures and order of operations).
-
-```js
-const mapObject = (arr, fn) =>
- (a => (
- (a = [arr, arr.map(fn)]), a[0].reduce((acc, val, ind) => ((acc[val] = a[1][ind]), acc), {})
- ))();
-```
-
-Examples
-
-```js
-const squareIt = arr => mapObject(arr, a => a * a);
-squareIt([1, 2, 3]); // { 1: 1, 2: 4, 3: 9 }
-```
-
[⬆ Back to top](#contents)
-
-### maxN
-
-Returns the `n` maximum elements from the provided array.
-If `n` is greater than or equal to the provided array's length, then return the original array (sorted in descending order).
-
-Use `Array.prototype.sort()` combined with the spread operator (`...`) to create a shallow clone of the array and sort it in descending order.
-Use `Array.prototype.slice()` to get the specified number of elements.
-Omit the second argument, `n`, to get a one-element array.
-
-```js
-const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n);
-```
-
-Examples
-
-```js
-maxN([1, 2, 3]); // [3]
-maxN([1, 2, 3], 2); // [3,2]
-```
-
[⬆ Back to top](#contents)
-
-### minN
-
-Returns the `n` minimum elements from the provided array.
-If `n` is greater than or equal to the provided array's length, then return the original array (sorted in ascending order).
-
-Use `Array.prototype.sort()` combined with the spread operator (`...`) to create a shallow clone of the array and sort it in ascending order.
-Use `Array.prototype.slice()` to get the specified number of elements.
-Omit the second argument, `n`, to get a one-element array.
-
-```js
-const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n);
-```
-
-Examples
-
-```js
-minN([1, 2, 3]); // [1]
-minN([1, 2, 3], 2); // [1,2]
-```
-
[⬆ Back to top](#contents)
-
-### none
-
-Returns `true` if the provided predicate function returns `false` for all elements in a collection, `false` otherwise.
-
-Use `Array.prototype.some()` to test if any elements in the collection return `true` based on `fn`.
-Omit the second argument, `fn`, to use `Boolean` as a default.
-
-```js
-const none = (arr, fn = Boolean) => !arr.some(fn);
-```
-
-Examples
-
-```js
-none([0, 1, 3, 0], x => x == 2); // true
-none([0, 0, 0]); // true
-```
-
[⬆ Back to top](#contents)
-
-### nthElement
-
-Returns the nth element of an array.
-
-Use `Array.prototype.slice()` to get an array containing the nth element at the first place.
-If the index is out of bounds, return `undefined`.
-Omit the second argument, `n`, to get the first element of the array.
-
-```js
-const nthElement = (arr, n = 0) => (n === -1 ? arr.slice(n) : arr.slice(n, n + 1))[0];
-```
-
-Examples
-
-```js
-nthElement(['a', 'b', 'c'], 1); // 'b'
-nthElement(['a', 'b', 'b'], -3); // 'a'
-```
-
[⬆ Back to top](#contents)
-
-### offset
-
-Moves the specified amount of elements to the end of the array.
-
-Use `Array.prototype.slice()` twice to get the elements after the specified index and the elements before that.
-Use the spread operator(`...`) to combine the two into one array.
-If `offset` is negative, the elements will be moved from end to start.
-
-```js
-const offset = (arr, offset) => [...arr.slice(offset), ...arr.slice(0, offset)];
-```
-
-Examples
-
-```js
-offset([1, 2, 3, 4, 5], 2); // [3, 4, 5, 1, 2]
-offset([1, 2, 3, 4, 5], -2); // [4, 5, 1, 2, 3]
-```
-
[⬆ Back to top](#contents)
-
-### partition
-
-Groups the elements into two arrays, depending on the provided function's truthiness for each element.
-
-Use `Array.prototype.reduce()` to create an array of two arrays.
-Use `Array.prototype.push()` to add elements for which `fn` returns `true` to the first array and elements for which `fn` returns `false` to the second one.
-
-```js
-const partition = (arr, fn) =>
- arr.reduce(
- (acc, val, i, arr) => {
- acc[fn(val, i, arr) ? 0 : 1].push(val);
- return acc;
- },
- [[], []]
- );
-```
-
-Examples
-
-```js
-const users = [{ user: 'barney', age: 36, active: false }, { user: 'fred', age: 40, active: true }];
-partition(users, o => o.active); // [[{ 'user': 'fred', 'age': 40, 'active': true }],[{ 'user': 'barney', 'age': 36, 'active': false }]]
-```
-
[⬆ Back to top](#contents)
-
-### permutations 
-
-Generates all permutations of an array's elements (contains duplicates).
-
-⚠️ **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.
-
-Use recursion.
-For each element in the given array, create all the partial permutations for the rest of its elements.
-Use `Array.prototype.map()` to combine the element with each partial permutation, then `Array.prototype.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])
- ),
- []
- );
-};
-```
-
-Examples
-
-```js
-permutations([1, 33, 5]); // [ [ 1, 33, 5 ], [ 1, 5, 33 ], [ 33, 1, 5 ], [ 33, 5, 1 ], [ 5, 1, 33 ], [ 5, 33, 1 ] ]
-```
-
[⬆ Back to top](#contents)
-
-### pull
-
-Mutates the original array to filter out the values specified.
-
-Use `Array.prototype.filter()` and `Array.prototype.includes()` to pull out the values that are not needed.
-Use `Array.prototype.length = 0` to mutate the passed in an array by resetting it's length to zero and `Array.prototype.push()` to re-populate it with only the pulled values.
-
-```js
-const pull = (arr, ...args) => {
- let argState = Array.isArray(args[0]) ? args[0] : args;
- let pulled = arr.filter((v, i) => !argState.includes(v));
- arr.length = 0;
- pulled.forEach(v => arr.push(v));
-};
-```
-
-Examples
-
-```js
-let myArray = ['a', 'b', 'c', 'a', 'b', 'c'];
-pull(myArray, 'a', 'c'); // myArray = [ 'b', 'b' ]
-```
-
[⬆ Back to top](#contents)
-
-### pullAtIndex 
-
-Mutates the original array to filter out the values at the specified indexes.
-
-Use `Array.prototype.filter()` and `Array.prototype.includes()` to pull out the values that are not needed.
-Use `Array.prototype.length = 0` to mutate the passed in an array by resetting it's length to zero and `Array.prototype.push()` to re-populate it with only the pulled values.
-Use `Array.prototype.push()` to keep track of pulled values
-
-```js
-const pullAtIndex = (arr, pullArr) => {
- let removed = [];
- let pulled = arr
- .map((v, i) => (pullArr.includes(i) ? removed.push(v) : v))
- .filter((v, i) => !pullArr.includes(i));
- arr.length = 0;
- pulled.forEach(v => arr.push(v));
- return removed;
-};
-```
-
-Examples
-
-```js
-let myArray = ['a', 'b', 'c', 'd'];
-let pulled = pullAtIndex(myArray, [1, 3]); // myArray = [ 'a', 'c' ] , pulled = [ 'b', 'd' ]
-```
-
[⬆ Back to top](#contents)
-
-### pullAtValue 
-
-Mutates the original array to filter out the values specified. Returns the removed elements.
-
-Use `Array.prototype.filter()` and `Array.prototype.includes()` to pull out the values that are not needed.
-Use `Array.prototype.length = 0` to mutate the passed in an array by resetting it's length to zero and `Array.prototype.push()` to re-populate it with only the pulled values.
-Use `Array.prototype.push()` to keep track of pulled values
-
-```js
-const pullAtValue = (arr, pullArr) => {
- let removed = [],
- pushToRemove = arr.forEach((v, i) => (pullArr.includes(v) ? removed.push(v) : v)),
- mutateTo = arr.filter((v, i) => !pullArr.includes(v));
- arr.length = 0;
- mutateTo.forEach(v => arr.push(v));
- return removed;
-};
-```
-
-Examples
-
-```js
-let myArray = ['a', 'b', 'c', 'd'];
-let pulled = pullAtValue(myArray, ['b', 'd']); // myArray = [ 'a', 'c' ] , pulled = [ 'b', 'd' ]
-```
-
[⬆ Back to top](#contents)
-
-### pullBy 
-
-Mutates the original array to filter out the values specified, based on a given iterator function.
-
-Check if the last argument provided in a function.
-Use `Array.prototype.map()` to apply the iterator function `fn` to all array elements.
-Use `Array.prototype.filter()` and `Array.prototype.includes()` to pull out the values that are not needed.
-Use `Array.prototype.length = 0` to mutate the passed in an array by resetting it's length to zero and `Array.prototype.push()` to re-populate it with only the pulled values.
-
-```js
-const pullBy = (arr, ...args) => {
- const length = args.length;
- let fn = length > 1 ? args[length - 1] : undefined;
- fn = typeof fn == 'function' ? (args.pop(), fn) : undefined;
- let argState = (Array.isArray(args[0]) ? args[0] : args).map(val => fn(val));
- let pulled = arr.filter((v, i) => !argState.includes(fn(v)));
- arr.length = 0;
- pulled.forEach(v => arr.push(v));
-};
-```
-
-Examples
-
-```js
-var myArray = [{ x: 1 }, { x: 2 }, { x: 3 }, { x: 1 }];
-pullBy(myArray, [{ x: 1 }, { x: 3 }], o => o.x); // myArray = [{ x: 2 }]
-```
-
[⬆ Back to top](#contents)
-
-### reducedFilter
-
-Filter an array of objects based on a condition while also filtering out unspecified keys.
-
-Use `Array.prototype.filter()` to filter the array based on the predicate `fn` so that it returns the objects for which the condition returned a truthy value.
-On the filtered array, use `Array.prototype.map()` to return the new object using `Array.prototype.reduce()` to filter out the keys which were not supplied as the `keys` argument.
-
-```js
-const reducedFilter = (data, keys, fn) =>
- data.filter(fn).map(el =>
- keys.reduce((acc, key) => {
- acc[key] = el[key];
- return acc;
- }, {})
- );
-```
-
-Examples
-
-```js
-const data = [
- {
- id: 1,
- name: 'john',
- age: 24
- },
- {
- id: 2,
- name: 'mike',
- age: 50
- }
-];
-
-reducedFilter(data, ['id', 'name'], item => item.age > 24); // [{ id: 2, name: 'mike'}]
-```
-
[⬆ Back to top](#contents)
-
-### 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.prototype.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]);
-```
-
-Examples
-
-```js
-reduceSuccessive([1, 2, 3, 4, 5, 6], (acc, val) => acc + val, 0); // [0, 1, 3, 6, 10, 15, 21]
-```
-
[⬆ Back to top](#contents)
-
-### reduceWhich
-
-Returns the minimum/maximum value of an array, after applying the provided function to set comparing rule.
-
-Use `Array.prototype.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));
-```
-
-Examples
-
-```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}
-```
-
[⬆ Back to top](#contents)
-
-### reject
-
-Filters an array's values based on a predicate function, returning only values for which the predicate function returns `true`.
-
-Use `Array.prototype.filter()` in combination with the predicate function, `pred`, to return only the values for which `pred()` returns `true`.
-
-```js
-const reject = (pred, array) => array.filter((...args) => !pred(...args));
-```
-
-Examples
-
-```js
-reject(x => x % 2 === 0, [1, 2, 3, 4, 5]); // [1, 3, 5]
-reject(word => word.length > 4, ['Apple', 'Pear', 'Kiwi', 'Banana']); // ['Pear', 'Kiwi']
-```
-
[⬆ Back to top](#contents)
-
-### remove
-
-Removes elements from an array for which the given function returns `false`.
-
-Use `Array.prototype.filter()` to find array elements that return truthy values and `Array.prototype.reduce()` to remove elements using `Array.prototype.splice()`.
-The `func` is invoked with three arguments (`value, index, array`).
-
-```js
-const remove = (arr, func) =>
- Array.isArray(arr)
- ? arr.filter(func).reduce((acc, val) => {
- arr.splice(arr.indexOf(val), 1);
- return acc.concat(val);
- }, [])
- : [];
-```
-
-Examples
-
-```js
-remove([1, 2, 3, 4], n => n % 2 === 0); // [2, 4]
-```
-
[⬆ Back to top](#contents)
-
-### sample
-
-Returns a random element from an array.
-
-Use `Math.random()` to generate a random number, multiply it by `length` and round it off to the nearest whole number using `Math.floor()`.
-This method also works with strings.
-
-```js
-const sample = arr => arr[Math.floor(Math.random() * arr.length)];
-```
-
-Examples
-
-```js
-sample([3, 7, 9, 11]); // 9
-```
-
[⬆ Back to top](#contents)
-
-### sampleSize
-
-Gets `n` random elements at unique keys from `array` up to the size of `array`.
-
-Shuffle the array using the [Fisher-Yates algorithm](https://github.com/30-seconds/30-seconds-of-code#shuffle).
-Use `Array.prototype.slice()` to get the first `n` elements.
-Omit the second argument, `n` to get only one element at random from the array.
-
-```js
-const sampleSize = ([...arr], n = 1) => {
- let m = arr.length;
- while (m) {
- const i = Math.floor(Math.random() * m--);
- [arr[m], arr[i]] = [arr[i], arr[m]];
- }
- return arr.slice(0, n);
-};
-```
-
-Examples
-
-```js
-sampleSize([1, 2, 3], 2); // [3,1]
-sampleSize([1, 2, 3], 4); // [2,3,1]
-```
-
[⬆ Back to top](#contents)
-
-### shank
-
-Has the same functionality as [`Array.prototype.splice()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice), but returning a new array instead of mutating the original array.
-
-Use `Array.prototype.slice()` and `Array.prototype.concat()` to get a new array with the new contents after removing existing elements and/or adding new elements.
-Omit the second argument, `index`, to start at `0`.
-Omit the third argument, `delCount`, to remove `0` elements.
-Omit the fourth argument, `elements`, in order to not add any new elements.
-
-```js
-const shank = (arr, index = 0, delCount = 0, ...elements) =>
- arr
- .slice(0, index)
- .concat(elements)
- .concat(arr.slice(index + delCount));
-```
-
-Examples
-
-```js
-const names = ['alpha', 'bravo', 'charlie'];
-const namesAndDelta = shank(names, 1, 0, 'delta'); // [ 'alpha', 'delta', 'bravo', 'charlie' ]
-const namesNoBravo = shank(names, 1, 1); // [ 'alpha', 'charlie' ]
-console.log(names); // ['alpha', 'bravo', 'charlie']
-```
-
[⬆ Back to top](#contents)
-
-### shuffle
-
-Randomizes the order of the values of an array, returning a new array.
-
-Uses the [Fisher-Yates algorithm](https://github.com/30-seconds/30-seconds-of-code#shuffle) to reorder the elements of the array.
-
-```js
-const shuffle = ([...arr]) => {
- let m = arr.length;
- while (m) {
- const i = Math.floor(Math.random() * m--);
- [arr[m], arr[i]] = [arr[i], arr[m]];
- }
- return arr;
-};
-```
-
-Examples
-
-```js
-const foo = [1, 2, 3];
-shuffle(foo); // [2, 3, 1], foo = [1, 2, 3]
-```
-
[⬆ Back to top](#contents)
-
-### similarity
-
-Returns an array of elements that appear in both arrays.
-
-Use `Array.prototype.filter()` to remove values that are not part of `values`, determined using `Array.prototype.includes()`.
-
-```js
-const similarity = (arr, values) => arr.filter(v => values.includes(v));
-```
-
-Examples
-
-```js
-similarity([1, 2, 3], [1, 2, 4]); // [1, 2]
-```
-
[⬆ Back to top](#contents)
-
-### sortedIndex
-
-Returns the lowest 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.prototype.findIndex()` to find the appropriate index where the element should be inserted.
-
-```js
-const sortedIndex = (arr, n) => {
- const isDescending = arr[0] > arr[arr.length - 1];
- const index = arr.findIndex(el => (isDescending ? n >= el : n <= el));
- return index === -1 ? arr.length : index;
-};
-```
-
-Examples
-
-```js
-sortedIndex([5, 3, 2, 1], 4); // 1
-sortedIndex([30, 50], 40); // 1
-```
-
[⬆ Back to top](#contents)
-
-### sortedIndexBy
-
-Returns the lowest 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.prototype.findIndex()` to find the appropriate index where the element should be inserted, based on the iterator function `fn`.
-
-```js
-const sortedIndexBy = (arr, n, fn) => {
- const isDescending = fn(arr[0]) > fn(arr[arr.length - 1]);
- const val = fn(n);
- const index = arr.findIndex(el => (isDescending ? val >= fn(el) : val <= fn(el)));
- return index === -1 ? arr.length : index;
-};
-```
-
-Examples
-
-```js
-sortedIndexBy([{ x: 4 }, { x: 5 }], { x: 4 }, o => o.x); // 0
-```
-
[⬆ Back to top](#contents)
-
-### 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.prototype.reverse()` and `Array.prototype.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.reverse().findIndex(el => (isDescending ? n <= el : n >= el));
- return index === -1 ? 0 : arr.length - index;
-};
-```
-
-Examples
-
-```js
-sortedLastIndex([10, 20, 30, 30, 40], 30); // 4
-```
-
[⬆ Back to top](#contents)
-
-### sortedLastIndexBy
-
-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.prototype.map()` to apply the iterator function to all elements of the array.
-Use `Array.prototype.reverse()` and `Array.prototype.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(fn)
- .reverse()
- .findIndex(el => (isDescending ? val <= el : val >= el));
- return index === -1 ? 0 : arr.length - index;
-};
-```
-
-Examples
-
-```js
-sortedLastIndexBy([{ x: 4 }, { x: 5 }], { x: 4 }, o => o.x); // 1
-```
-
[⬆ Back to top](#contents)
-
-### stableSort 
-
-Performs stable sorting of an array, preserving the initial indexes of items when their values are the same.
-Does not mutate the original array, but returns a new array instead.
-
-Use `Array.prototype.map()` to pair each element of the input array with its corresponding index.
-Use `Array.prototype.sort()` and a `compare` function to sort the list, preserving their initial order if the items compared are equal.
-Use `Array.prototype.map()` to convert back to the initial array items.
-
-```js
-const stableSort = (arr, compare) =>
- arr
- .map((item, index) => ({ item, index }))
- .sort((a, b) => compare(a.item, b.item) || a.index - b.index)
- .map(({ item }) => item);
-```
-
-Examples
-
-```js
-const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-const stable = stableSort(arr, () => 0); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-```
-
[⬆ Back to top](#contents)
-
-### symmetricDifference
-
-Returns the symmetric difference between two arrays, without filtering out duplicate values.
-
-Create a `Set` from each array, then use `Array.prototype.filter()` on each of them to only keep values not contained in the other.
-
-```js
-const symmetricDifference = (a, b) => {
- const sA = new Set(a),
- sB = new Set(b);
- return [...a.filter(x => !sB.has(x)), ...b.filter(x => !sA.has(x))];
-};
-```
-
-Examples
-
-```js
-symmetricDifference([1, 2, 3], [1, 2, 4]); // [3, 4]
-symmetricDifference([1, 2, 2], [1, 3, 1]); // [2, 2, 3]
-```
-
[⬆ Back to top](#contents)
-
-### 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.prototype.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)))];
-};
-```
-
-Examples
-
-```js
-symmetricDifferenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [ 1.2, 3.4 ]
-```
-
[⬆ Back to top](#contents)
-
-### symmetricDifferenceWith
-
-Returns the symmetric difference between two arrays, using a provided function as a comparator.
-
-Use `Array.prototype.filter()` and `Array.prototype.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)
-];
-```
-
-Examples
-
-```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]
-```
-
[⬆ Back to top](#contents)
-
-### tail
-
-Returns all elements in an array except for the first one.
-
-Return `Array.prototype.slice(1)` if the array's `length` is more than `1`, otherwise, return the whole array.
-
-```js
-const tail = arr => (arr.length > 1 ? arr.slice(1) : arr);
-```
-
-Examples
-
-```js
-tail([1, 2, 3]); // [2,3]
-tail([1]); // [1]
-```
-
[⬆ Back to top](#contents)
-
-### take
-
-Returns an array with n elements removed from the beginning.
-
-Use `Array.prototype.slice()` to create a slice of the array with `n` elements taken from the beginning.
-
-```js
-const take = (arr, n = 1) => arr.slice(0, n);
-```
-
-Examples
-
-```js
-take([1, 2, 3], 5); // [1, 2, 3]
-take([1, 2, 3], 0); // []
-```
-
[⬆ Back to top](#contents)
-
-### takeRight
-
-Returns an array with n elements removed from the end.
-
-Use `Array.prototype.slice()` to create a slice of the array with `n` elements taken from the end.
-
-```js
-const takeRight = (arr, n = 1) => arr.slice(arr.length - n, arr.length);
-```
-
-Examples
-
-```js
-takeRight([1, 2, 3], 2); // [ 2, 3 ]
-takeRight([1, 2, 3]); // [3]
-```
-
[⬆ Back to top](#contents)
-
-### takeRightWhile
-
-Removes elements from the end of an array until the passed function returns `true`. Returns the removed elements.
-
-Loop through the array, using a `Array.prototype.reduceRight()` and accumulating elements while the function returns falsy value.
-
-```js
-const takeRightWhile = (arr, func) =>
- arr.reduceRight((acc, el) => (func(el) ? acc : [el, ...acc]), []);
-```
-
-Examples
-
-```js
-takeRightWhile([1, 2, 3, 4], n => n < 3); // [3, 4]
-```
-
[⬆ Back to top](#contents)
-
-### takeWhile
-
-Removes elements in an array until the passed function returns `true`. Returns the removed elements.
-
-Loop through the array, using a `for...of` loop over `Array.prototype.entries()` until the returned value from the function is `true`.
-Return the removed elements, using `Array.prototype.slice()`.
-
-```js
-const takeWhile = (arr, func) => {
- for (const [i, val] of arr.entries()) if (func(val)) return arr.slice(0, i);
- return arr;
-};
-```
-
-Examples
-
-```js
-takeWhile([1, 2, 3, 4], n => n >= 3); // [1, 2]
-```
-
[⬆ Back to top](#contents)
-
-### toHash
-
-Reduces a given Array-like into a value hash (keyed data store).
-
-Given an Iterable or Array-like structure, call `Array.prototype.reduce.call()` on the provided object to step over it and return an Object, keyed by the reference value.
-
-```js
-const toHash = (object, key) =>
- Array.prototype.reduce.call(
- object,
- (acc, data, index) => ((acc[!key ? index : data[key]] = data), acc),
- {}
- );
-```
-
-Examples
-
-```js
-toHash([4, 3, 2, 1]); // { 0: 4, 1: 3, 2: 2, 3: 1 }
-toHash([{ a: 'label' }], 'a'); // { label: { a: 'label' } }
-// A more in depth example:
-let users = [{ id: 1, first: 'Jon' }, { id: 2, first: 'Joe' }, { id: 3, first: 'Moe' }];
-let managers = [{ manager: 1, employees: [2, 3] }];
-// We use function here because we want a bindable reference, but a closure referencing the hash would work, too.
-managers.forEach(
- manager =>
- (manager.employees = manager.employees.map(function(id) {
- return this[id];
- }, toHash(users, 'id')))
-);
-managers; // [ { manager:1, employees: [ { id: 2, first: "Joe" }, { id: 3, first: "Moe" } ] } ]
-```
-
[⬆ Back to top](#contents)
-
-### union
-
-Returns every element that exists in any of the two arrays once.
-
-Create a `Set` with all values of `a` and `b` and convert to an array.
-
-```js
-const union = (a, b) => Array.from(new Set([...a, ...b]));
-```
-
-Examples
-
-```js
-union([1, 2, 3], [4, 3, 2]); // [1,2,3,4]
-```
-
[⬆ Back to top](#contents)
-
-### 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(fn));
- return Array.from(new Set([...a, ...b.filter(x => !s.has(fn(x)))]));
-};
-```
-
-Examples
-
-```js
-unionBy([2.1], [1.2, 2.3], Math.floor); // [2.1, 1.2]
-```
-
[⬆ Back to top](#contents)
-
-### 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.prototype.findIndex()`.
-
-```js
-const unionWith = (a, b, comp) =>
- Array.from(new Set([...a, ...b.filter(x => a.findIndex(y => comp(x, y)) === -1)]));
-```
-
-Examples
-
-```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]
-```
-
[⬆ Back to top](#contents)
-
-### uniqueElements
-
-Returns all unique values of an array.
-
-Use ES6 `Set` and the `...rest` operator to discard all duplicated values.
-
-```js
-const uniqueElements = arr => [...new Set(arr)];
-```
-
-Examples
-
-```js
-uniqueElements([1, 2, 2, 3, 4, 4, 5]); // [1, 2, 3, 4, 5]
-```
-
[⬆ Back to top](#contents)
-
-### uniqueElementsBy
-
-Returns all unique values of an array, based on a provided comparator function.
-
-Use `Array.prototype.reduce()` and `Array.prototype.some()` for an array containing only the first unique occurrence of each value, based on the comparator function, `fn`.
-The comparator function takes two arguments: the values of the two elements being compared.
-
-```js
-const uniqueElementsBy = (arr, fn) =>
- arr.reduce((acc, v) => {
- if (!acc.some(x => fn(v, x))) acc.push(v);
- return acc;
- }, []);
-```
-
-Examples
-
-```js
-uniqueElementsBy(
- [
- { id: 0, value: 'a' },
- { id: 1, value: 'b' },
- { id: 2, value: 'c' },
- { id: 1, value: 'd' },
- { id: 0, value: 'e' }
- ],
- (a, b) => a.id == b.id
-); // [ { id: 0, value: 'a' }, { id: 1, value: 'b' }, { id: 2, value: 'c' } ]
-```
-
[⬆ Back to top](#contents)
-
-### uniqueElementsByRight
-
-Returns all unique values of an array, based on a provided comparator function, starting from the right.
-
-Use `Array.prototype.reduceRight()` and `Array.prototype.some()` for an array containing only the last unique occurrence of each value, based on the comparator function, `fn`.
-The comparator function takes two arguments: the values of the two elements being compared.
-
-```js
-const uniqueElementsByRight = (arr, fn) =>
- arr.reduceRight((acc, v) => {
- if (!acc.some(x => fn(v, x))) acc.push(v);
- return acc;
- }, []);
-```
-
-Examples
-
-```js
-uniqueElementsByRight(
- [
- { id: 0, value: 'a' },
- { id: 1, value: 'b' },
- { id: 2, value: 'c' },
- { id: 1, value: 'd' },
- { id: 0, value: 'e' }
- ],
- (a, b) => a.id == b.id
-); // [ { id: 0, value: 'e' }, { id: 1, value: 'd' }, { id: 2, value: 'c' } ]
-```
-
[⬆ Back to top](#contents)
-
-### uniqueSymmetricDifference
-
-Returns the unique symmetric difference between two arrays, not containing duplicate values from either array.
-
-Use `Array.prototype.filter()` and `Array.prototype.includes()` on each array to remove values contained in the other, then create a `Set` from the results, removing duplicate values.
-
-```js
-const uniqueSymmetricDifference = (a, b) => [
- ...new Set([...a.filter(v => !b.includes(v)), ...b.filter(v => !a.includes(v))])
-];
-```
-
-Examples
-
-```js
-uniqueSymmetricDifference([1, 2, 3], [1, 2, 4]); // [3, 4]
-uniqueSymmetricDifference([1, 2, 2], [1, 3, 1]); // [2, 3]
-```
-
[⬆ Back to top](#contents)
-
-### 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.prototype.map()` to make each element an array.
-Use `Array.prototype.reduce()` and `Array.prototype.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 => [])
- );
-```
-
-Examples
-
-```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]]
-```
-
[⬆ Back to top](#contents)
-
-### 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.prototype.map()` to make each element an array.
-Use `Array.prototype.reduce()` and `Array.prototype.forEach()` to map grouped values to individual arrays.
-Use `Array.prototype.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));
-```
-
-Examples
-
-```js
-unzipWith([[1, 10, 100], [2, 20, 200]], (...args) => args.reduce((acc, v) => acc + v, 0)); // [3, 30, 300]
-```
-
[⬆ Back to top](#contents)
-
-### without
-
-Filters out the elements of an array, that have one of the specified values.
-
-Use `Array.prototype.filter()` to create an array excluding(using `!Array.includes()`) all given values.
-
-```js
-const without = (arr, ...args) => arr.filter(v => !args.includes(v));
-```
-
-Examples
-
-```js
-without([2, 1, 2, 3], 1, 2); // [3]
-```
-
[⬆ Back to top](#contents)
-
-### xProd
-
-Creates a new array out of the two supplied by creating each possible pair from the arrays.
-
-Use `Array.prototype.reduce()`, `Array.prototype.map()` and `Array.prototype.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])), []);
-```
-
-Examples
-
-```js
-xProd([1, 2], ['a', 'b']); // [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]
-```
-
[⬆ Back to top](#contents)
-
-### zip
-
-Creates an array of elements, grouped based on the position in the original arrays.
-
-Use `Math.max.apply()` 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.
-
-```js
-const zip = (...arrays) => {
- const maxLength = Math.max(...arrays.map(x => x.length));
- return Array.from({ length: maxLength }).map((_, i) => {
- return Array.from({ length: arrays.length }, (_, k) => arrays[k][i]);
- });
-};
-```
-
-Examples
-
-```js
-zip(['a', 'b'], [1, 2], [true, false]); // [['a', 1, true], ['b', 2, false]]
-zip(['a'], [1, 2], [true, false]); // [['a', 1, true], [undefined, 2, false]]
-```
-
[⬆ Back to top](#contents)
-
-### zipObject
-
-Given an array of valid property identifiers and an array of values, return an object associating the properties to the values.
-
-Since an object can have undefined values but not undefined property pointers, the array of properties is used to decide the structure of the resulting object using `Array.prototype.reduce()`.
-
-```js
-const zipObject = (props, values) =>
- props.reduce((obj, prop, index) => ((obj[prop] = values[index]), obj), {});
-```
-
-Examples
-
-```js
-zipObject(['a', 'b', 'c'], [1, 2]); // {a: 1, b: 2, c: undefined}
-zipObject(['a', 'b'], [1, 2, 3]); // {a: 1, b: 2}
-```
-
[⬆ Back to top](#contents)
-
-### 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 is 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 = (...array) => {
- const fn = typeof array[array.length - 1] === 'function' ? array.pop() : undefined;
- return Array.from({ length: Math.max(...array.map(a => a.length)) }, (_, i) =>
- fn ? fn(...array.map(a => a[i])) : array.map(a => a[i])
- );
-};
-```
-
-Examples
-
-```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']
-```
-
[⬆ Back to top](#contents)
-
----
-
-## 🌐 Browser
-
-
-### arrayToHtmlList
-
-Converts the given array elements into `