From 0a0a753df728eea04e732e066265b42b41997611 Mon Sep 17 00:00:00 2001 From: King Date: Tue, 12 Dec 2017 11:30:50 -0500 Subject: [PATCH 001/202] add chunk-array.md --- snippets/chunk-array.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/chunk-array.md diff --git a/snippets/chunk-array.md b/snippets/chunk-array.md new file mode 100644 index 000000000..7ee72a85d --- /dev/null +++ b/snippets/chunk-array.md @@ -0,0 +1,14 @@ +### Chunk Array + +Creates an array of elements split into groups the length of size. +If array can't be split evenly, the final chunk will be the remaining elements. + +```js +const chunk = (arr, size) => + Array + .apply(null, {length: Math.ceil(arr.length/size) }) + .map((value, index) => arr.slice(index*size, index*size+size) ) + +// const myArray = [2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 2]; +// chunk(myArray, 3) -> [ [ 2, 2, 2 ], [ 2, 2, 2 ], [ 3, 2, 3 ], [ 2, 3, 2 ], [ 2 ] ] +``` \ No newline at end of file From e0fcf9fe05206ae899c9e06c72627f4789d0a70f Mon Sep 17 00:00:00 2001 From: Robin Thomas <> Date: Tue, 12 Dec 2017 10:24:42 -0600 Subject: [PATCH 002/202] Added async function chain --- snippets/chain-async-functions.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 snippets/chain-async-functions.md diff --git a/snippets/chain-async-functions.md b/snippets/chain-async-functions.md new file mode 100644 index 000000000..528fcb1a6 --- /dev/null +++ b/snippets/chain-async-functions.md @@ -0,0 +1,15 @@ +### Chain asynchronous functions + +Loop through an array of functions containing asynchronous events, calling `next` when each asynchronous event has completed. + +```js +const chainAsync = fns => { + let curr = 0; const next = () => fns[curr++](next); next() +} +chainAsync([ + next => { console.log('This happens at 0 seconds'); setTimeout(next, 1000) }, + next => { console.log('This happens at 1 second'); setTimeout(next, 1000) }, + next => { console.log('This happens at 2 seconds'); setTimeout(next, 1000) }, + next => { console.log('Done at 3 seconds!') } +]) +``` From dcea680b08184398a5e72ffdb494ba79aecd3cd9 Mon Sep 17 00:00:00 2001 From: Christopher Engels Date: Tue, 12 Dec 2017 19:18:53 +0100 Subject: [PATCH 003/202] Refactor measure-time-taken-by-function from spread syntax to callback function --- snippets/measure-time-taken-by-function.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/snippets/measure-time-taken-by-function.md b/snippets/measure-time-taken-by-function.md index 8586f59d1..4b9fe33a2 100644 --- a/snippets/measure-time-taken-by-function.md +++ b/snippets/measure-time-taken-by-function.md @@ -4,10 +4,10 @@ Use `performance.now()` to get start and end time for the function, `console.log First argument is the function name, subsequent arguments are passed to the function. ```js -const timeTaken = (func,...args) => { - var t0 = performance.now(), r = func(...args); +const timeTaken = callback => { + const t0 = performance.now(), r = callback(); console.log(performance.now() - t0); return r; } -// timeTaken(Math.pow, 2, 10) -> 1024 (0.010000000009313226 logged in console) +// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) ``` From 4f8bbf4733e5a36d7b336e737a39fe9099c640ca Mon Sep 17 00:00:00 2001 From: macsmac Date: Wed, 13 Dec 2017 00:33:36 +0500 Subject: [PATCH 004/202] Added getType function --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 640da6cd9..e6e38b36a 100644 --- a/README.md +++ b/README.md @@ -261,6 +261,15 @@ const arrayMin = arr => Math.min(...arr); // arrayMin([10, 1, 5]) -> 1 ``` +### Get native type of value + +Returns lower-cased constructor name of value, "undefined" or "null" if value is undefined or null + +```js +const getType = v => v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); +// getType(new Set([1,2,3])) -> "set" +``` + ### Get scroll position Use `pageXOffset` and `pageYOffset` if they are defined, otherwise `scrollLeft` and `scrollTop`. From f0982a01a374741048ccac2e70fc5ce41e0e02e8 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Tue, 12 Dec 2017 22:23:44 +0200 Subject: [PATCH 005/202] Make 'Anagrams of string' fully functional Gets rid of mutable `.push` (and param reassignment) inside `.map` --- snippets/anagrams-of-string-(with-duplicates).md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/snippets/anagrams-of-string-(with-duplicates).md b/snippets/anagrams-of-string-(with-duplicates).md index 0d24e51cb..090a75b9d 100644 --- a/snippets/anagrams-of-string-(with-duplicates).md +++ b/snippets/anagrams-of-string-(with-duplicates).md @@ -9,8 +9,7 @@ Base cases are for string `length` equal to `2` or `1`. const anagrams = str => { if(str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; return str.split('').reduce( (acc, letter, i) => { - anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => acc.push(letter + val) ); - return acc; + return acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => letter + val )); }, []); } // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] From 76a97266eeb3d09b242e5b085a7d2f0f6cf82747 Mon Sep 17 00:00:00 2001 From: Jussi Saurio Date: Tue, 12 Dec 2017 22:28:46 +0200 Subject: [PATCH 006/202] build readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 640da6cd9..d891348fc 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,7 @@ Base cases are for string `length` equal to `2` or `1`. const anagrams = str => { if(str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; return str.split('').reduce( (acc, letter, i) => { - anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => acc.push(letter + val) ); - return acc; + return acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => letter + val )); }, []); } // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] From 15827ebf23357a13781091afc9d0fb2de87dda09 Mon Sep 17 00:00:00 2001 From: Adrian Klimek Date: Tue, 12 Dec 2017 22:37:34 +0100 Subject: [PATCH 007/202] Simplify isEven function --- README.md | 6 +++--- snippets/even-or-odd-number.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 640da6cd9..93fbac389 100644 --- a/README.md +++ b/README.md @@ -195,11 +195,11 @@ const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); ### Even or odd number -Use `Math.abs()` to extend logic to negative numbers, check using the modulo (`%`) operator. -Return `true` if the number is even, `false` if the number is odd. +Checks whether number is odd or even using the modulo (`%`) operator. +Returns `true` if the number is even, `false` if the number is odd. ```js -const isEven = num => Math.abs(num) % 2 === 0; +const isEven = num => num % 2 === 0; // isEven(3) -> false ``` diff --git a/snippets/even-or-odd-number.md b/snippets/even-or-odd-number.md index 605108429..1399bb593 100644 --- a/snippets/even-or-odd-number.md +++ b/snippets/even-or-odd-number.md @@ -1,9 +1,9 @@ ### Even or odd number -Use `Math.abs()` to extend logic to negative numbers, check using the modulo (`%`) operator. -Return `true` if the number is even, `false` if the number is odd. +Checks whether number is odd or even using the modulo (`%`) operator. +Returns `true` if the number is even, `false` if the number is odd. ```js -const isEven = num => Math.abs(num) % 2 === 0; +const isEven = num => num % 2 === 0; // isEven(3) -> false ``` From 1dcb8244e1b0f63ab91d9e4df4768d515613ee12 Mon Sep 17 00:00:00 2001 From: Sergei Zelinsky Date: Wed, 13 Dec 2017 00:02:52 +0200 Subject: [PATCH 008/202] fix deep flatten array implementation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 640da6cd9..6dff38d61 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ Use `reduce()` to get all elements that are not arrays, flatten each element tha ```js const deepFlatten = arr => - arr.reduce( (a, v) => a.concat( Array.isArray(v) ? flatten(v) : v ), []); + arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []); // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] ``` From 05d3a8b0e2cc055b0a33aaa6472cee53bf2c136d Mon Sep 17 00:00:00 2001 From: Adrian Klimek Date: Tue, 12 Dec 2017 23:11:03 +0100 Subject: [PATCH 009/202] Update the snippet description (odd or even number) --- snippets/even-or-odd-number.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/even-or-odd-number.md b/snippets/even-or-odd-number.md index 1399bb593..24eb312e6 100644 --- a/snippets/even-or-odd-number.md +++ b/snippets/even-or-odd-number.md @@ -1,6 +1,6 @@ ### Even or odd number -Checks whether number is odd or even using the modulo (`%`) operator. +Checks whether a number is odd or even using the modulo (`%`) operator. Returns `true` if the number is even, `false` if the number is odd. ```js From 868f043ea05f3dd359617d5a642ef02b215a2f9a Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 00:11:27 +0200 Subject: [PATCH 010/202] Build README --- README.md | 4 ++-- snippets/deep-flatten-array.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6dff38d61..f5ccbea25 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ Use `reduce()` to get all elements that are not arrays, flatten each element tha ```js const deepFlatten = arr => - arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []); + arr.reduce( (a, v) => a.concat( Array.isArray(v) ? deepFlatten(v) : v ), []); // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] ``` @@ -240,7 +240,7 @@ Use `reduce()` to get all elements inside the array and `concat()` to flatten th ```js const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); -// flatten([1,[2],3,4) -> [1,2,3,4] +// flatten([1,[2],3,4]) -> [1,2,3,4] ``` ### Get max value from array diff --git a/snippets/deep-flatten-array.md b/snippets/deep-flatten-array.md index 545c4c8d4..472143583 100644 --- a/snippets/deep-flatten-array.md +++ b/snippets/deep-flatten-array.md @@ -5,6 +5,6 @@ Use `reduce()` to get all elements that are not arrays, flatten each element tha ```js const deepFlatten = arr => - arr.reduce( (a, v) => a.concat( Array.isArray(v) ? flatten(v) : v ), []); + arr.reduce( (a, v) => a.concat( Array.isArray(v) ? deepFlatten(v) : v ), []); // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] ``` From 576b96a0f85a0310f079e02e36e677b36cca1977 Mon Sep 17 00:00:00 2001 From: Elder Henrique Souza Date: Tue, 12 Dec 2017 20:26:01 -0200 Subject: [PATCH 011/202] refactor to account for variadic functions altough certainly more verbose, this version accounts for variadic functions such as Math.min that can't represent it's arity with the length property properly. for such cases you can pass the optional argument arity (as in the edited example). what do you think? --- snippets/curry.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/snippets/curry.md b/snippets/curry.md index a700ac776..78cf79702 100644 --- a/snippets/curry.md +++ b/snippets/curry.md @@ -5,8 +5,15 @@ If the number of provided arguments (`args`) is sufficient, call the passed func Otherwise return a curried function `f` that expects the rest of the arguments. ```js -const curry = f => - (...args) => - args.length >= f.length ? f(...args) : (...otherArgs) => curry(f)(...args, ...otherArgs); +const curry = (f, arity = f.length, next) => + (next = prevArgs => + nextArg => { + const args = [ ...prevArgs, nextArg ] + return args.length >= arity + ? f(...args) + : next(args); + } + )([]); // curry(Math.pow)(2)(10) -> 1024 +// curry(Math.min, 3)(10)(50)(2) -> 2 ``` From 28c2a2e4b6fb485cc83edf2c1e4ddfd82e07bf17 Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 09:47:16 +1100 Subject: [PATCH 012/202] Create random-integer-in-range.md --- snippets/random-integer-in-range.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/random-integer-in-range.md diff --git a/snippets/random-integer-in-range.md b/snippets/random-integer-in-range.md new file mode 100644 index 000000000..3bf615a88 --- /dev/null +++ b/snippets/random-integer-in-range.md @@ -0,0 +1,9 @@ +### Random integer in range + +Use `Math.random()` to generate a random number and map it to the desired range, using `Math.floor()` to make it an integer. + +```js +const randomIntegerInRange = (min, max) => + Math.floor(Math.random() * (max - min + 1)) + min; +// randomIntegerInRange(0, 5) -> 2 +``` From d1ee29934256c1cf99da3e5108d93aa250b00202 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 00:49:17 +0200 Subject: [PATCH 013/202] Build README --- README.md | 10 ++++++++++ snippets/random-integer-in-range.md | 3 +-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f5ccbea25..87b66d7ae 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ * [Object from key value pairs](#object-from-key-value-pairs) * [Pipe](#pipe) * [Powerset](#powerset) +* [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) * [Redirect to url](#redirect-to-url) @@ -374,6 +375,15 @@ const powerset = arr => // powerset([1,2]) -> [[], [1], [2], [2,1]] ``` +### Random integer in range + +Use `Math.random()` to generate a random number and map it to the desired range, using `Math.floor()` to make it an integer. + +```js +const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; +// randomIntegerInRange(0, 5) -> 2 +``` + ### Random number in range Use `Math.random()` to generate a random value, map it to the desired range using multiplication. diff --git a/snippets/random-integer-in-range.md b/snippets/random-integer-in-range.md index 3bf615a88..78bb85ab0 100644 --- a/snippets/random-integer-in-range.md +++ b/snippets/random-integer-in-range.md @@ -3,7 +3,6 @@ Use `Math.random()` to generate a random number and map it to the desired range, using `Math.floor()` to make it an integer. ```js -const randomIntegerInRange = (min, max) => - Math.floor(Math.random() * (max - min + 1)) + min; +const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; // randomIntegerInRange(0, 5) -> 2 ``` From ccbe7c510a27ae2a85b1fa13cc1f1d8075252919 Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 10:03:49 +1100 Subject: [PATCH 014/202] Create median-of-array-of.md --- snippets/median-of-array-of.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 snippets/median-of-array-of.md diff --git a/snippets/median-of-array-of.md b/snippets/median-of-array-of.md new file mode 100644 index 000000000..0a9c4eab2 --- /dev/null +++ b/snippets/median-of-array-of.md @@ -0,0 +1,17 @@ +### Median of array of numbers + +Find the middle index of an array and sort the numbers in ascending order. If the length of the array is odd, +return the number at the midpoint, otherwise return the average of the two middle numbers. + +```js +const median = numbers => { + const midpoint = Math.floor(numbers.length / 2); + const sorted = numbers.sort((a, b) => a - b); + + return numbers.length % 2 + ? sorted[midpoint] + : (sorted[midpoint - 1] + sorted[midpoint]) / 2; +}; +// median([5,6,50,1,-5]) -> 5 +// median([0,10,-2,7]) -> 3.5 +``` From 5502174360f9a8dad7a2a01976c6b3d94329a5b5 Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 10:04:55 +1100 Subject: [PATCH 015/202] Rename median-of-array-of.md to median-of-array-of-numbers.md --- snippets/{median-of-array-of.md => median-of-array-of-numbers.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename snippets/{median-of-array-of.md => median-of-array-of-numbers.md} (100%) diff --git a/snippets/median-of-array-of.md b/snippets/median-of-array-of-numbers.md similarity index 100% rename from snippets/median-of-array-of.md rename to snippets/median-of-array-of-numbers.md From 556ef539fd8601c818a334fbce9948a89a18ac6d Mon Sep 17 00:00:00 2001 From: Farhad Date: Wed, 13 Dec 2017 09:15:41 +0330 Subject: [PATCH 016/202] Add bottomVisible --- README.md | 18 ++++++++++++++++++ snippets/bottom-visible.md | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 snippets/bottom-visible.md diff --git a/README.md b/README.md index 87b66d7ae..0341f5fa4 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ * [Anagrams of string (with duplicates)](#anagrams-of-string-with-duplicates) * [Average of array of numbers](#average-of-array-of-numbers) +* [Bottom visible](#bottom-visible) * [Capitalize first letter of every word](#capitalize-first-letter-of-every-word) * [Capitalize first letter](#capitalize-first-letter) * [Check for palindrome](#check-for-palindrome) @@ -85,6 +86,23 @@ const average = arr => // average([1,2,3]) -> 2 ``` +### Bottom visible + +Returns `true` if bottom of the page is visible. It adds `scrollY` to +the height of the visible portion of the page (`clientHeight`) and +compares it to `pageHeight` to see if bottom of the page is visible. + +```js +const bottomVisible = () => { + const scrollY = window.scrollY; + const visibleHeight = document.documentElement.clientHeight; + const pageHeight = document.documentElement.scrollHeight; + const bottomOfPage = visibleHeight + scrollY >= pageHeight; + + return bottomOfPage || pageHeight < visibleHeight; +} +``` + ### Capitalize first letter of every word Use `replace()` to match the first character of each word and `toUpperCase()` to capitalize it. diff --git a/snippets/bottom-visible.md b/snippets/bottom-visible.md new file mode 100644 index 000000000..403a157f8 --- /dev/null +++ b/snippets/bottom-visible.md @@ -0,0 +1,16 @@ +### Bottom visible + +Returns `true` if bottom of the page is visible. It adds `scrollY` to +the height of the visible portion of the page (`clientHeight`) and +compares it to `pageHeight` to see if bottom of the page is visible. + +```js +const bottomVisible = () => { + const scrollY = window.scrollY; + const visibleHeight = document.documentElement.clientHeight; + const pageHeight = document.documentElement.scrollHeight; + const bottomOfPage = visibleHeight + scrollY >= pageHeight; + + return bottomOfPage || pageHeight < visibleHeight; +} +``` From 203d646abc9c72be93870131eed8b794c4eebfbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Feje=C5=A1?= Date: Wed, 13 Dec 2017 08:34:42 +0100 Subject: [PATCH 017/202] Add value or default --- snippets/value-or-default.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 snippets/value-or-default.md diff --git a/snippets/value-or-default.md b/snippets/value-or-default.md new file mode 100644 index 000000000..0af9529e8 --- /dev/null +++ b/snippets/value-or-default.md @@ -0,0 +1,8 @@ +### Value or default + +Returns value, or default value if passed value is `falsy`. + +```js +const valueOrDefault = (value, d) => value || d; +// valueOrDefault(NaN, 30) -> 30 +``` From ed23eaf99e3e6c89ab4cc294e234ed23eeb9913f Mon Sep 17 00:00:00 2001 From: Mariam Date: Wed, 13 Dec 2017 11:13:16 +0300 Subject: [PATCH 018/202] Fixed a typo in README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 87b66d7ae..0509562ed 100644 --- a/README.md +++ b/README.md @@ -221,7 +221,7 @@ Create an empty array of the specific length, initializing the first two values Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. ```js -const fibonacci = n => +const fibonacci = n => Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),[]); // fibonacci(5) -> [0,1,1,2,3] ``` @@ -246,7 +246,7 @@ const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); ### Get max value from array -Use `Math.max()` combined with the spread operator (`...`) to get the minimum value in the array. +Use `Math.max()` combined with the spread operator (`...`) to get the maximum value in the array. ```js const arrayMax = arr => Math.max(...arr); @@ -553,4 +553,3 @@ const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); ## Credits *Icons made by [Smashicons](https://www.flaticon.com/authors/smashicons) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/).* - From 0a114151c024526b8da5ac3549b1c5c2a409a920 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 11:30:39 +0200 Subject: [PATCH 019/202] Fix typo in snippet file --- README.md | 3 ++- snippets/get-max-value-from-array.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0509562ed..7b4bb82ee 100644 --- a/README.md +++ b/README.md @@ -221,7 +221,7 @@ Create an empty array of the specific length, initializing the first two values Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. ```js -const fibonacci = n => +const fibonacci = n => Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),[]); // fibonacci(5) -> [0,1,1,2,3] ``` @@ -553,3 +553,4 @@ const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); ## Credits *Icons made by [Smashicons](https://www.flaticon.com/authors/smashicons) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/).* + diff --git a/snippets/get-max-value-from-array.md b/snippets/get-max-value-from-array.md index 55d90f1a7..2e724a3e2 100644 --- a/snippets/get-max-value-from-array.md +++ b/snippets/get-max-value-from-array.md @@ -1,6 +1,6 @@ ### Get max value from array -Use `Math.max()` combined with the spread operator (`...`) to get the minimum value in the array. +Use `Math.max()` combined with the spread operator (`...`) to get the maximum value in the array. ```js const arrayMax = arr => Math.max(...arr); From e330ff3f8ff1b4b076a28e4aba50caf373c68309 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 11:32:52 +0200 Subject: [PATCH 020/202] Build README --- README.md | 4 +++- snippets/get-native-type-of-value.md | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 snippets/get-native-type-of-value.md diff --git a/README.md b/README.md index e3ca069fa..007a096bd 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ * [Flatten array](#flatten-array) * [Get max value from array](#get-max-value-from-array) * [Get min value from array](#get-min-value-from-array) +* [Get native type of value](#get-native-type-of-value) * [Get scroll position](#get-scroll-position) * [Greatest common divisor (GCD)](#greatest-common-divisor-gcd) * [Head of list](#head-of-list) @@ -267,7 +268,8 @@ const arrayMin = arr => Math.min(...arr); Returns lower-cased constructor name of value, "undefined" or "null" if value is undefined or null ```js -const getType = v => v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); +const getType = v => + v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); // getType(new Set([1,2,3])) -> "set" ``` diff --git a/snippets/get-native-type-of-value.md b/snippets/get-native-type-of-value.md new file mode 100644 index 000000000..d2ded3f83 --- /dev/null +++ b/snippets/get-native-type-of-value.md @@ -0,0 +1,9 @@ +### Get native type of value + +Returns lower-cased constructor name of value, "undefined" or "null" if value is undefined or null + +```js +const getType = v => + v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); +// getType(new Set([1,2,3])) -> "set" +``` From c170b49fcbc7170052a4b01df3b0b539052141c4 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 11:36:56 +0200 Subject: [PATCH 021/202] Build README --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 007a096bd..e3bb1076c 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ * [URL parameters](#url-parameters) * [UUID generator](#uuid-generator) * [Validate number](#validate-number) +* [Value or default](#value-or-default) ### Anagrams of string (with duplicates) @@ -561,6 +562,15 @@ const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); // validateNumber('10') -> true ``` +### Value or default + +Returns value, or default value if passed value is `falsy`. + +```js +const valueOrDefault = (value, d) => value || d; +// valueOrDefault(NaN, 30) -> 30 +``` + ## Credits *Icons made by [Smashicons](https://www.flaticon.com/authors/smashicons) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/).* From ca95624a1e342c71e5026bd1d1ccd938eda045d6 Mon Sep 17 00:00:00 2001 From: Sven Luijten Date: Wed, 13 Dec 2017 10:37:33 +0100 Subject: [PATCH 022/202] use const in snippet template --- snippet-template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippet-template.md b/snippet-template.md index 02148e458..e258fe079 100644 --- a/snippet-template.md +++ b/snippet-template.md @@ -3,7 +3,7 @@ Explain briefly how the snippet works ```js -var functionName = arguments => +const functionName = arguments => {functionBody} // functionName(sampleInput) -> sampleOutput ``` From f53f1e4a5247d2d14f04a8e632fdfccc097cf598 Mon Sep 17 00:00:00 2001 From: Hendra Susanto Date: Wed, 13 Dec 2017 16:37:41 +0700 Subject: [PATCH 023/202] Check for array length in tail function to return the correct value for single-value arrays. --- README.md | 3 ++- snippets/tail-of-list.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7b4bb82ee..6ea3b089c 100644 --- a/README.md +++ b/README.md @@ -503,8 +503,9 @@ Use array destructuring to swap values between two variables. Return `arr.slice(1)`. ```js -const tail = arr => arr.slice(1); +const tail = arr => arr.length > 1 ? arr.slice(1) : arr; // tail([1,2,3]) -> [2,3] +// tail([1]) -> [1] ``` ### Unique values of array diff --git a/snippets/tail-of-list.md b/snippets/tail-of-list.md index 9a9513262..cecca8e8e 100644 --- a/snippets/tail-of-list.md +++ b/snippets/tail-of-list.md @@ -3,6 +3,7 @@ Return `arr.slice(1)`. ```js -const tail = arr => arr.slice(1); +const tail = arr => arr.length > 1 ? arr.slice(1) : arr; // tail([1,2,3]) -> [2,3] +// tail([1]) -> [1] ``` From 07d4086c184cf45bd5b9dbc42aa22c62a583ad49 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 11:40:27 +0200 Subject: [PATCH 024/202] Updated tail description --- README.md | 2 +- snippets/tail-of-list.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 57433ebb1..e8088ff33 100644 --- a/README.md +++ b/README.md @@ -512,7 +512,7 @@ Use array destructuring to swap values between two variables. ### Tail of list -Return `arr.slice(1)`. +Return `arr.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; diff --git a/snippets/tail-of-list.md b/snippets/tail-of-list.md index cecca8e8e..d0c9681c3 100644 --- a/snippets/tail-of-list.md +++ b/snippets/tail-of-list.md @@ -1,6 +1,6 @@ ### Tail of list -Return `arr.slice(1)`. +Return `arr.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; From 85709fccda5d1ded080d1592948f3187fe30e4ad Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Wed, 13 Dec 2017 10:44:44 +0100 Subject: [PATCH 025/202] Add run-promises-in-series --- README.md | 13 ++++++++++++- snippets/run-promises-in-series.md | 9 +++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 snippets/run-promises-in-series.md diff --git a/README.md b/README.md index 640da6cd9..7b6fa91ec 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ * [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) +* [Run promises in series](#run-promises-in-series) * [Scroll to top](#scroll-to-top) * [Shuffle array values](#shuffle-array-values) * [Similarity between arrays](#similarity-between-arrays) @@ -240,7 +241,7 @@ Use `reduce()` to get all elements inside the array and `concat()` to flatten th ```js const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); -// flatten([1,[2],3,4) -> [1,2,3,4] +// flatten([1,[2],3,4]) -> [1,2,3,4] ``` ### Get max value from array @@ -422,6 +423,16 @@ const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6 // rgbToHex(255, 165, 1) -> 'ffa501' ``` +### Run promises in series + +Run an array of promises in series using `Array.reduce()` by creating a promise chain, where each promise returns the next promise when resolved. + +```js +var series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); +// var delay = (d) => new Promise(r => setTimeout(r, d)) +// series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete +``` + ### Scroll to top Get distance from top using `document.documentElement.scrollTop` or `document.body.scrollTop`. diff --git a/snippets/run-promises-in-series.md b/snippets/run-promises-in-series.md new file mode 100644 index 000000000..b22d9e00f --- /dev/null +++ b/snippets/run-promises-in-series.md @@ -0,0 +1,9 @@ +### Run promises in series + +Run an array of promises in series using `Array.reduce()` by creating a promise chain, where each promise returns the next promise when resolved. + +```js +var series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); +// var delay = (d) => new Promise(r => setTimeout(r, d)) +// series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete +``` From c905200acbaf0a8840ae5657ce271186da2ae296 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 11:47:51 +0200 Subject: [PATCH 026/202] Update median, build README --- README.md | 15 +++++++++++++++ snippets/median-of-array-of-numbers.md | 16 ++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e8088ff33..b778a14b2 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ * [Initialize array with values](#initialize-array-with-values) * [Last of list](#last-of-list) * [Measure time taken by function](#measure-time-taken-by-function) +* [Median of array of numbers](#median-of-array-of-numbers) * [Object from key value pairs](#object-from-key-value-pairs) * [Pipe](#pipe) * [Powerset](#powerset) @@ -359,6 +360,20 @@ const timeTaken = (func,...args) => { // timeTaken(Math.pow, 2, 10) -> 1024 (0.010000000009313226 logged in console) ``` +### Median of array of numbers + +Find the middle of the array, use `Array.sort()` to sort the values. +Return the number at the midpoint if `length` is odd, otherwise the average of the two middle numbers. + +```js +const median = arr => { + const mid = Math.floor(arr.length / 2), nums = arr.sort((a,b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +} +// median([5,6,50,1,-5]) -> 5 +// median([0,10,-2,7]) -> 3.5 +``` + ### Object from key-value pairs Use `Array.reduce()` to create and combine key-value pairs. diff --git a/snippets/median-of-array-of-numbers.md b/snippets/median-of-array-of-numbers.md index 0a9c4eab2..3a675a545 100644 --- a/snippets/median-of-array-of-numbers.md +++ b/snippets/median-of-array-of-numbers.md @@ -1,17 +1,13 @@ ### Median of array of numbers -Find the middle index of an array and sort the numbers in ascending order. If the length of the array is odd, -return the number at the midpoint, otherwise return the average of the two middle numbers. +Find the middle of the array, use `Array.sort()` to sort the values. +Return the number at the midpoint if `length` is odd, otherwise the average of the two middle numbers. ```js -const median = numbers => { - const midpoint = Math.floor(numbers.length / 2); - const sorted = numbers.sort((a, b) => a - b); - - return numbers.length % 2 - ? sorted[midpoint] - : (sorted[midpoint - 1] + sorted[midpoint]) / 2; -}; +const median = arr => { + const mid = Math.floor(arr.length / 2), nums = arr.sort((a,b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +} // median([5,6,50,1,-5]) -> 5 // median([0,10,-2,7]) -> 3.5 ``` From a6723a3c37818ae2c92880ec77b60d35fcf4efba Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Wed, 13 Dec 2017 10:57:42 +0100 Subject: [PATCH 027/202] Use const --- README.md | 4 ++-- snippets/run-promises-in-series.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7b6fa91ec..79fd2a21a 100644 --- a/README.md +++ b/README.md @@ -428,8 +428,8 @@ const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6 Run an array of promises in series using `Array.reduce()` by creating a promise chain, where each promise returns the next promise when resolved. ```js -var series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); -// var delay = (d) => new Promise(r => setTimeout(r, d)) +const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); +// const delay = (d) => new Promise(r => setTimeout(r, d)) // series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete ``` diff --git a/snippets/run-promises-in-series.md b/snippets/run-promises-in-series.md index b22d9e00f..2193e8df4 100644 --- a/snippets/run-promises-in-series.md +++ b/snippets/run-promises-in-series.md @@ -3,7 +3,7 @@ Run an array of promises in series using `Array.reduce()` by creating a promise chain, where each promise returns the next promise when resolved. ```js -var series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); -// var delay = (d) => new Promise(r => setTimeout(r, d)) +const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); +// const delay = (d) => new Promise(r => setTimeout(r, d)) // series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete ``` From 49716dcb9d6d0166eeb59479c95656f45939eefe Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 12:04:30 +0200 Subject: [PATCH 028/202] Update chunk-array.md Updated description --- snippets/chunk-array.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/snippets/chunk-array.md b/snippets/chunk-array.md index 7ee72a85d..7953723f8 100644 --- a/snippets/chunk-array.md +++ b/snippets/chunk-array.md @@ -1,14 +1,13 @@ ### Chunk Array -Creates an array of elements split into groups the length of size. -If array can't be split evenly, the final chunk will be the remaining elements. +Use `Array.apply()` to create a new array, that fits the number of chunks that will be produced. +Use `Array.map()` 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 - .apply(null, {length: Math.ceil(arr.length/size) }) - .map((value, index) => arr.slice(index*size, index*size+size) ) + Array.apply(null, {length: Math.ceil(arr.length/size)}).map((v, i) => arr.slice(i*size, i*size+size)); // const myArray = [2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 2]; // chunk(myArray, 3) -> [ [ 2, 2, 2 ], [ 2, 2, 2 ], [ 3, 2, 3 ], [ 2, 3, 2 ], [ 2 ] ] -``` \ No newline at end of file +``` From 3aed33b6df00c5696ebb8a321a6c6615c79ed413 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 12:06:05 +0200 Subject: [PATCH 029/202] Improved chunk snippet, build README --- README.md | 13 +++++++++++++ snippets/chunk-array.md | 8 +++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6af096779..7308593a0 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ * [Capitalize first letter of every word](#capitalize-first-letter-of-every-word) * [Capitalize first letter](#capitalize-first-letter) * [Check for palindrome](#check-for-palindrome) +* [Chunk array](#chunk-array) * [Count occurrences of a value in array](#count-occurrences-of-a-value-in-array) * [Current URL](#current-url) * [Curry](#curry) @@ -120,6 +121,18 @@ const palindrome = str => // palindrome('taco cat') -> true ``` +### Chunk array + +Use `Array.apply()` to create a new array, that fits the number of chunks that will be produced. +Use `Array.map()` 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.apply(null, {length: Math.ceil(arr.length/size)}).map((v, i) => arr.slice(i*size, i*size+size)); +// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] +``` + ### Count occurrences of a value in array Use `reduce()` to increment a counter each time you encounter the specific value inside the array. diff --git a/snippets/chunk-array.md b/snippets/chunk-array.md index 7953723f8..8f92499a2 100644 --- a/snippets/chunk-array.md +++ b/snippets/chunk-array.md @@ -1,13 +1,11 @@ -### Chunk Array +### Chunk array Use `Array.apply()` to create a new array, that fits the number of chunks that will be produced. Use `Array.map()` 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) => +const chunk = (arr, size) => Array.apply(null, {length: Math.ceil(arr.length/size)}).map((v, i) => arr.slice(i*size, i*size+size)); - -// const myArray = [2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 2]; -// chunk(myArray, 3) -> [ [ 2, 2, 2 ], [ 2, 2, 2 ], [ 3, 2, 3 ], [ 2, 3, 2 ], [ 2 ] ] +// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` From 30b9a70db103b6a9a2ca22a7bf4c5a0acd1393d1 Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Wed, 13 Dec 2017 11:09:40 +0100 Subject: [PATCH 030/202] Fix filename typo --- ...in-an-array.md => filter-out-non-unique-values-in-an-array.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename snippets/{filter-out-non-uniqe-values-in-an-array.md => filter-out-non-unique-values-in-an-array.md} (100%) diff --git a/snippets/filter-out-non-uniqe-values-in-an-array.md b/snippets/filter-out-non-unique-values-in-an-array.md similarity index 100% rename from snippets/filter-out-non-uniqe-values-in-an-array.md rename to snippets/filter-out-non-unique-values-in-an-array.md From 1193a3fc8461cbe1d684c01338c54e415a2dd6e3 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 12:12:12 +0200 Subject: [PATCH 031/202] Update chain-async-functions.md Improved example and formatting --- snippets/chain-async-functions.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/snippets/chain-async-functions.md b/snippets/chain-async-functions.md index 528fcb1a6..5962f29ff 100644 --- a/snippets/chain-async-functions.md +++ b/snippets/chain-async-functions.md @@ -3,13 +3,12 @@ Loop through an array of functions containing asynchronous events, calling `next` when each asynchronous event has completed. ```js -const chainAsync = fns => { - let curr = 0; const next = () => fns[curr++](next); next() -} +const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); } +/* chainAsync([ - next => { console.log('This happens at 0 seconds'); setTimeout(next, 1000) }, - next => { console.log('This happens at 1 second'); setTimeout(next, 1000) }, - next => { console.log('This happens at 2 seconds'); setTimeout(next, 1000) }, - next => { console.log('Done at 3 seconds!') } + next => { console.log('0 seconds'); setTimeout(next, 1000); }, + next => { console.log('1 second'); setTimeout(next, 1000); }, + next => { console.log('2 seconds');} ]) +*/ ``` From c0ed8da9fddba70e6cba9bb9492300ae8af2e986 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 12:13:34 +0200 Subject: [PATCH 032/202] Build README --- README.md | 16 ++++++++++++++++ ...ctions.md => chain-asynchronous-functions.md} | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) rename snippets/{chain-async-functions.md => chain-asynchronous-functions.md} (90%) diff --git a/README.md b/README.md index 7308593a0..6c1f8c196 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ * [Average of array of numbers](#average-of-array-of-numbers) * [Capitalize first letter of every word](#capitalize-first-letter-of-every-word) * [Capitalize first letter](#capitalize-first-letter) +* [Chain asynchronous functions](#chain-asynchronous-functions) * [Check for palindrome](#check-for-palindrome) * [Chunk array](#chunk-array) * [Count occurrences of a value in array](#count-occurrences-of-a-value-in-array) @@ -110,6 +111,21 @@ const capitalize = (str, lowerRest = false) => // capitalize('myName', true) -> 'Myname' ``` +### Chain asynchronous functions + +Loop through an array of functions containing asynchronous events, calling `next` when each asynchronous event has completed. + +```js +const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); } +/* +chainAsync([ + next => { console.log('0 seconds'); setTimeout(next, 1000); }, + next => { console.log('1 second'); setTimeout(next, 1000); }, + next => { console.log('2 seconds'); } +]) +*/ +``` + ### Check for palindrome Convert string `toLowerCase()` and use `replace()` to remove non-alphanumeric characters from it. diff --git a/snippets/chain-async-functions.md b/snippets/chain-asynchronous-functions.md similarity index 90% rename from snippets/chain-async-functions.md rename to snippets/chain-asynchronous-functions.md index 5962f29ff..6c6118b3c 100644 --- a/snippets/chain-async-functions.md +++ b/snippets/chain-asynchronous-functions.md @@ -4,11 +4,11 @@ Loop through an array of functions containing asynchronous events, calling `next ```js const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); } -/* +/* chainAsync([ next => { console.log('0 seconds'); setTimeout(next, 1000); }, next => { console.log('1 second'); setTimeout(next, 1000); }, - next => { console.log('2 seconds');} + next => { console.log('2 seconds'); } ]) */ ``` From 4569c18ad622548a43f48749bfe10754707746de Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 12:14:45 +0200 Subject: [PATCH 033/202] Build README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c1f8c196..b56e503d5 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ * [Even or odd number](#even-or-odd-number) * [Factorial](#factorial) * [Fibonacci array generator](#fibonacci-array-generator) -* [Filter out non uniqe values in an array](#filter-out-non-uniqe-values-in-an-array) +* [Filter out non unique values in an array](#filter-out-non-unique-values-in-an-array) * [Flatten array](#flatten-array) * [Get max value from array](#get-max-value-from-array) * [Get min value from array](#get-min-value-from-array) From fd4597560d52fe7654747d705b3364da08c7c4de Mon Sep 17 00:00:00 2001 From: Daniel Ramos Date: Wed, 13 Dec 2017 10:27:43 +0000 Subject: [PATCH 034/202] Create promisify.md --- README.md | 19 +++++++++++++++++++ snippets/promisify.md | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 snippets/promisify.md diff --git a/README.md b/README.md index 7308593a0..557d44232 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ * [Object from key value pairs](#object-from-key-value-pairs) * [Pipe](#pipe) * [Powerset](#powerset) +* [Promisify](#promisify) * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) @@ -416,6 +417,24 @@ const powerset = arr => // powerset([1,2]) -> [[], [1], [2], [2,1]] ``` +### Promisify + +Creates a promise version of the given callback-style function. In Node 8+, you +can use [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original) + +```js +const promisify = func => + (...args) => + new Promise((resolve, reject) => + func(...args, (err, result) => + err + ? reject(err) + : resolve(result)) + ) +// const stat = promisify(fs.stat) +// When called, stat returns a promise +``` + ### Random integer in range Use `Math.random()` to generate a random number and map it to the desired range, using `Math.floor()` to make it an integer. diff --git a/snippets/promisify.md b/snippets/promisify.md new file mode 100644 index 000000000..b2007a5ab --- /dev/null +++ b/snippets/promisify.md @@ -0,0 +1,17 @@ +### Promisify + +Creates a promise version of the given callback-style function. In Node 8+, you +can use [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original) + +```js +const promisify = func => + (...args) => + new Promise((resolve, reject) => + func(...args, (err, result) => + err + ? reject(err) + : resolve(result)) + ) +// const stat = promisify(fs.stat) +// When called, stat returns a promise +``` From b74ba8bbfc700b2c4ffb1866a63b7bc0df78d8ee Mon Sep 17 00:00:00 2001 From: Daniel Ramos Date: Wed, 13 Dec 2017 10:29:34 +0000 Subject: [PATCH 035/202] Fixed typo in promisify.md --- README.md | 2 +- snippets/promisify.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 557d44232..ea30128d0 100644 --- a/README.md +++ b/README.md @@ -419,7 +419,7 @@ const powerset = arr => ### Promisify -Creates a promise version of the given callback-style function. In Node 8+, you +Creates a promisified version of the given callback-style function. In Node 8+, you can use [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original) ```js diff --git a/snippets/promisify.md b/snippets/promisify.md index b2007a5ab..efecd794a 100644 --- a/snippets/promisify.md +++ b/snippets/promisify.md @@ -1,6 +1,6 @@ ### Promisify -Creates a promise version of the given callback-style function. In Node 8+, you +Creates a promisified version of the given callback-style function. In Node 8+, you can use [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original) ```js From f8ee54604bcd0bf0f7b54a388a803cc2cfb8c695 Mon Sep 17 00:00:00 2001 From: Daniel Ramos Date: Wed, 13 Dec 2017 10:33:39 +0000 Subject: [PATCH 036/202] Improving example in promisify.md --- README.md | 2 +- snippets/promisify.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ea30128d0..01a7f9c30 100644 --- a/README.md +++ b/README.md @@ -432,7 +432,7 @@ const promisify = func => : resolve(result)) ) // const stat = promisify(fs.stat) -// When called, stat returns a promise +// stat('foo.txt') -> Promise resolves if `foo.txt` exists, otherwise rejects ``` ### Random integer in range diff --git a/snippets/promisify.md b/snippets/promisify.md index efecd794a..b1c34a20c 100644 --- a/snippets/promisify.md +++ b/snippets/promisify.md @@ -13,5 +13,5 @@ const promisify = func => : resolve(result)) ) // const stat = promisify(fs.stat) -// When called, stat returns a promise +// stat('foo.txt') -> Promise resolves if `foo.txt` exists, otherwise rejects ``` From 3bef1644cad97d1b90529caad12867d5fce3797a Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 12:37:28 +0200 Subject: [PATCH 037/202] Update anagrams-of-string-(with-duplicates).md Removed unnecessary curly brackets --- snippets/anagrams-of-string-(with-duplicates).md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/snippets/anagrams-of-string-(with-duplicates).md b/snippets/anagrams-of-string-(with-duplicates).md index 090a75b9d..10b949654 100644 --- a/snippets/anagrams-of-string-(with-duplicates).md +++ b/snippets/anagrams-of-string-(with-duplicates).md @@ -8,9 +8,8 @@ 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) => { - return acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => letter + val )); - }, []); + return str.split('').reduce( (acc, letter, i) => + acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => letter + val )), []); } // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` From 3b38f2e7a9425754ad9de7125009c83570da3986 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 12:38:12 +0200 Subject: [PATCH 038/202] Build README --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5d3c89d81..a5b84b1f7 100644 --- a/README.md +++ b/README.md @@ -73,9 +73,8 @@ 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) => { - return acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => letter + val )); - }, []); + return str.split('').reduce( (acc, letter, i) => + acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => letter + val )), []); } // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` From 1a0d41d2b87d93537d9d1ed7b0d7342e68de89c0 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 12:39:24 +0200 Subject: [PATCH 039/202] Update promisify.md --- snippets/promisify.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/snippets/promisify.md b/snippets/promisify.md index b1c34a20c..d6b437589 100644 --- a/snippets/promisify.md +++ b/snippets/promisify.md @@ -8,9 +8,7 @@ const promisify = func => (...args) => new Promise((resolve, reject) => func(...args, (err, result) => - err - ? reject(err) - : resolve(result)) + err ? reject(err) : resolve(result)); ) // const stat = promisify(fs.stat) // stat('foo.txt') -> Promise resolves if `foo.txt` exists, otherwise rejects From 95bc5de53fa681597af0c07664b0f44c14dfedb9 Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 21:50:16 +1100 Subject: [PATCH 040/202] Create percentile.md https://www.easycalculation.com/statistics/percentile-rank.php Feel free to try and one-linerify it if possible, lol --- snippets/percentile.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 snippets/percentile.md diff --git a/snippets/percentile.md b/snippets/percentile.md new file mode 100644 index 000000000..70d303d1a --- /dev/null +++ b/snippets/percentile.md @@ -0,0 +1,18 @@ +### Percentile + +Calculate how many numbers are below the value and how many are the same value and +apply the percentile formula. + +```js +const percentile = (arr, val) => { + let below = 0, same = 0; + + for (const number of arr) { + if (number < val) below++; + if (number === val) same++; + } + + return 100 * (below + (0.5 * same)) / arr.length; +}; +// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 + ``` From 529d9b2720cbb80281eb8bfe9fc59abf4ecfbd0c Mon Sep 17 00:00:00 2001 From: Meet Zaveri Date: Wed, 13 Dec 2017 16:25:15 +0530 Subject: [PATCH 041/202] Create truncate_a_string.md --- snippets/truncate_a_string.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/truncate_a_string.md diff --git a/snippets/truncate_a_string.md b/snippets/truncate_a_string.md new file mode 100644 index 000000000..a3bc9321d --- /dev/null +++ b/snippets/truncate_a_string.md @@ -0,0 +1,14 @@ +### Truncate a String + +First we start off with a simple if statement to determine one of three outcomes… +If our string length is greater than the num we want to truncate at, and our truncate point is at least three characters or more into the string, we return a slice of our string starting at character 0, and ending at num - 3. We then append our '...' to the end of the string. +However, if our string length is greater than the num but num is within the first three characters, we don’t have to count our dots as characters. Therefore, we return the same string as above, with one difference: The endpoint of our slice is now just num. +Finally, if none of the above situations are true, it means our string length is less than our truncation num. Therefore, we can just return the string. + +``` +function truncateString(str, num) { + if (str.length > num) + return str.slice(0, num > 3 ? num-3 : num) + '...'; + return str; +} +``` From 619c361f7417f389ad8817508560d80ddeedfb62 Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 22:18:49 +1100 Subject: [PATCH 042/202] Update percentile.md --- snippets/percentile.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/snippets/percentile.md b/snippets/percentile.md index 70d303d1a..4be44782a 100644 --- a/snippets/percentile.md +++ b/snippets/percentile.md @@ -1,18 +1,10 @@ ### Percentile -Calculate how many numbers are below the value and how many are the same value and +Use `Array.filter()` to calculate how many numbers are below the value and how many are the same value and apply the percentile formula. ```js -const percentile = (arr, val) => { - let below = 0, same = 0; - - for (const number of arr) { - if (number < val) below++; - if (number === val) same++; - } - - return 100 * (below + (0.5 * same)) / arr.length; -}; +const percentile = (arr, val) => + 100 * (arr.filter(v => v < val).length + 0.5 * arr.filter(v => v === val).length) / arr.length; // percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 ``` From 60d8afaf73dc91a362e798da4d46cfd82e7a8136 Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 22:23:11 +1100 Subject: [PATCH 043/202] use reduce magic --- snippets/percentile.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/snippets/percentile.md b/snippets/percentile.md index 4be44782a..271a90599 100644 --- a/snippets/percentile.md +++ b/snippets/percentile.md @@ -4,7 +4,7 @@ Use `Array.filter()` to calculate how many numbers are below the value and how m apply the percentile formula. ```js -const percentile = (arr, val) => - 100 * (arr.filter(v => v < val).length + 0.5 * arr.filter(v => v === val).length) / arr.length; +const percentile = (arr, val) => + 100 * arr.reduce((acc,v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; // percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 ``` From 8275fe5ffeb774b06f3fc588987e834fcf1e8261 Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 22:23:43 +1100 Subject: [PATCH 044/202] Update percentile.md --- snippets/percentile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/percentile.md b/snippets/percentile.md index 271a90599..eb72b711c 100644 --- a/snippets/percentile.md +++ b/snippets/percentile.md @@ -1,6 +1,6 @@ ### Percentile -Use `Array.filter()` to calculate how many numbers are below the value and how many are the same value and +Use `Array.reduce()` to calculate how many numbers are below the value and how many are the same value and apply the percentile formula. ```js From f850cea25a94d088f9ebb3c00a567af8ee37c3c8 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 13:28:38 +0200 Subject: [PATCH 045/202] Build README --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index a5b84b1f7..b3277f17e 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ * [Measure time taken by function](#measure-time-taken-by-function) * [Median of array of numbers](#median-of-array-of-numbers) * [Object from key value pairs](#object-from-key-value-pairs) +* [Percentile](#percentile) * [Pipe](#pipe) * [Powerset](#powerset) * [Random integer in range](#random-integer-in-range) @@ -411,6 +412,17 @@ const objectFromPairs = arr => arr.reduce((a,v) => (a[v[0]] = v[1], a), {}); // objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} ``` +### Percentile + +Use `Array.reduce()` to calculate how many numbers are below the value and how many are the same value and +apply the percentile formula. + +```js +const percentile = (arr, val) => + 100 * arr.reduce((acc,v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; +// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 + ``` + ### Pipe Use `Array.reduce()` to pass value through functions. From 3b63999bfb25dc9f03f0cd62cd528105a5a75d58 Mon Sep 17 00:00:00 2001 From: Elder Henrique Souza Date: Wed, 13 Dec 2017 09:31:25 -0200 Subject: [PATCH 046/202] Update curry.md --- snippets/curry.md | 1 + 1 file changed, 1 insertion(+) diff --git a/snippets/curry.md b/snippets/curry.md index 78cf79702..4bcfee3c6 100644 --- a/snippets/curry.md +++ b/snippets/curry.md @@ -3,6 +3,7 @@ Use recursion. If the number of provided arguments (`args`) is sufficient, call the passed function `f`. Otherwise return a curried function `f` that expects the rest of the arguments. +If you want to curry a function that accepts a variable number of arguments (variadic function) like Math.min for example, you can optionally pass the number of arguments to the second parameter arity. ```js const curry = (f, arity = f.length, next) => From c15eb63ad259a20894f4c68a601d08baa347df22 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 13:35:10 +0200 Subject: [PATCH 047/202] Build README --- README.md | 12 +++++++++--- snippets/curry.md | 12 +++++------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index b3277f17e..87b5208f4 100644 --- a/README.md +++ b/README.md @@ -171,12 +171,18 @@ const currentUrl = _ => window.location.href; Use recursion. If the number of provided arguments (`args`) is sufficient, call the passed function `f`. Otherwise return a curried function `f` that expects the rest of the arguments. +If you want to curry a function that accepts a variable number of arguments (a variadic function, e.g. `Math.min()`), you can optionally pass the number of arguments to the second parameter `arity`. ```js -const curry = f => - (...args) => - args.length >= f.length ? f(...args) : (...otherArgs) => curry(f)(...args, ...otherArgs); +const curry = (f, arity = f.length, next) => + (next = prevArgs => + nextArg => { + const args = [ ...prevArgs, nextArg ]; + return args.length >= arity ? f(...args) : next(args); + } + )([]); // curry(Math.pow)(2)(10) -> 1024 +// curry(Math.min, 3)(10)(50)(2) -> 2 ``` ### Deep flatten array diff --git a/snippets/curry.md b/snippets/curry.md index 4bcfee3c6..edb95461f 100644 --- a/snippets/curry.md +++ b/snippets/curry.md @@ -3,16 +3,14 @@ Use recursion. If the number of provided arguments (`args`) is sufficient, call the passed function `f`. Otherwise return a curried function `f` that expects the rest of the arguments. -If you want to curry a function that accepts a variable number of arguments (variadic function) like Math.min for example, you can optionally pass the number of arguments to the second parameter arity. +If you want to curry a function that accepts a variable number of arguments (a variadic function, e.g. `Math.min()`), you can optionally pass the number of arguments to the second parameter `arity`. ```js -const curry = (f, arity = f.length, next) => - (next = prevArgs => +const curry = (f, arity = f.length, next) => + (next = prevArgs => nextArg => { - const args = [ ...prevArgs, nextArg ] - return args.length >= arity - ? f(...args) - : next(args); + const args = [ ...prevArgs, nextArg ]; + return args.length >= arity ? f(...args) : next(args); } )([]); // curry(Math.pow)(2)(10) -> 1024 From 46a64738b661a66a39389ce554ee8b7bb9590c65 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 13:44:38 +0200 Subject: [PATCH 048/202] Update truncate_a_string.md Updated description and added example. --- snippets/truncate_a_string.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/snippets/truncate_a_string.md b/snippets/truncate_a_string.md index a3bc9321d..5c2a091cb 100644 --- a/snippets/truncate_a_string.md +++ b/snippets/truncate_a_string.md @@ -1,14 +1,10 @@ ### Truncate a String -First we start off with a simple if statement to determine one of three outcomes… -If our string length is greater than the num we want to truncate at, and our truncate point is at least three characters or more into the string, we return a slice of our string starting at character 0, and ending at num - 3. We then append our '...' to the end of the string. -However, if our string length is greater than the num but num is within the first three characters, we don’t have to count our dots as characters. Therefore, we return the same string as above, with one difference: The endpoint of our slice is now just num. -Finally, if none of the above situations are true, it means our string length is less than our truncation num. Therefore, we can just return the string. +Determine if the string's `length` is greater than `num`. +Return the string truncated to the desired length, with `...` appended to the end or the original string. ``` -function truncateString(str, num) { - if (str.length > num) - return str.slice(0, num > 3 ? num-3 : num) + '...'; - return str; -} +const truncate = (str, num) => + str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; +// truncate('boomerang', 7) -> 'boom...' ``` From 3bfba2bb69c4ee482a1e858381764f28c4d00f84 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 13:48:12 +0200 Subject: [PATCH 049/202] Build README --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 87b5208f4..303f34e39 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ * [Sum of array of numbers](#sum-of-array-of-numbers) * [Swap values of two variables](#swap-values-of-two-variables) * [Tail of list](#tail-of-list) +* [Truncate_a_string](#truncate_a_string) * [Unique values of array](#unique-values-of-array) * [URL parameters](#url-parameters) * [UUID generator](#uuid-generator) @@ -591,6 +592,17 @@ const tail = arr => arr.length > 1 ? arr.slice(1) : arr; // tail([1]) -> [1] ``` +### Truncate a String + +Determine if the string's `length` is greater than `num`. +Return the string truncated to the desired length, with `...` appended to the end or the original string. + +``` +const truncate = (str, num) => + str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; +// truncate('boomerang', 7) -> 'boom...' +``` + ### Unique values of array Use ES6 `Set` and the `...rest` operator to discard all duplicated values. From 768b21a57613b7438bcb37565f55cdf1bd44b3a7 Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Wed, 13 Dec 2017 12:52:07 +0100 Subject: [PATCH 050/202] Dashes not underscores --- README.md | 2 +- snippets/{truncate_a_string.md => truncate-a-string.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename snippets/{truncate_a_string.md => truncate-a-string.md} (100%) diff --git a/README.md b/README.md index 303f34e39..745ccf1f2 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ * [Sum of array of numbers](#sum-of-array-of-numbers) * [Swap values of two variables](#swap-values-of-two-variables) * [Tail of list](#tail-of-list) -* [Truncate_a_string](#truncate_a_string) +* [Truncate a string](#truncate-a-string) * [Unique values of array](#unique-values-of-array) * [URL parameters](#url-parameters) * [UUID generator](#uuid-generator) diff --git a/snippets/truncate_a_string.md b/snippets/truncate-a-string.md similarity index 100% rename from snippets/truncate_a_string.md rename to snippets/truncate-a-string.md From 259fc81d3afbebc075127d3d9c9ef6b0f8ac21fb Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 13:55:44 +0200 Subject: [PATCH 051/202] Build README --- README.md | 8 ++++---- snippets/measure-time-taken-by-function.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 303f34e39..dffb8d999 100644 --- a/README.md +++ b/README.md @@ -385,15 +385,15 @@ const last = arr => arr.slice(-1)[0]; ### Measure time taken by function Use `performance.now()` to get start and end time for the function, `console.log()` the time taken. -First argument is the function name, subsequent arguments are passed to the function. +Pass a callback function as the argument. ```js -const timeTaken = (func,...args) => { - var t0 = performance.now(), r = func(...args); +const timeTaken = callback => { + const t0 = performance.now(), r = callback(); console.log(performance.now() - t0); return r; } -// timeTaken(Math.pow, 2, 10) -> 1024 (0.010000000009313226 logged in console) +// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) ``` ### Median of array of numbers diff --git a/snippets/measure-time-taken-by-function.md b/snippets/measure-time-taken-by-function.md index 4b9fe33a2..73d32141e 100644 --- a/snippets/measure-time-taken-by-function.md +++ b/snippets/measure-time-taken-by-function.md @@ -1,7 +1,7 @@ ### Measure time taken by function Use `performance.now()` to get start and end time for the function, `console.log()` the time taken. -First argument is the function name, subsequent arguments are passed to the function. +Pass a callback function as the argument. ```js const timeTaken = callback => { From 52fb6f0a0a4f23a8bde3db6cef20cc534cc18300 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 13:59:14 +0200 Subject: [PATCH 052/202] Added note about ES6 and Babel --- README.md | 1 + static-parts/README-start.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index cd89af165..00127cc34 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ - Use Ctrl + F or command + F to search for a snippet. - Contributions welcome, please read [contribution guide](CONTRIBUTING.md). +- Snippets are written in ES6, if you want to ensure backwards-compatibility, please use the [Babel transpiler](https://babeljs.io/). ## Contents diff --git a/static-parts/README-start.md b/static-parts/README-start.md index 424b14964..b5e4eec03 100644 --- a/static-parts/README-start.md +++ b/static-parts/README-start.md @@ -5,5 +5,6 @@ - Use Ctrl + F or command + F to search for a snippet. - Contributions welcome, please read [contribution guide](CONTRIBUTING.md). +- Snippets are written in ES6, if you want to ensure backwards-compatibility, please use the [Babel transpiler](https://babeljs.io/). ## Contents From e9c534c3950c4cfb24cfce2c1beabd71498a2ec9 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 14:00:12 +0200 Subject: [PATCH 053/202] README wording --- README.md | 4 ++-- static-parts/README-start.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 00127cc34..7f583154b 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ > Curated collection of useful Javascript snippets that you can understand in 30 seconds or less. - Use Ctrl + F or command + F to search for a snippet. -- Contributions welcome, please read [contribution guide](CONTRIBUTING.md). -- Snippets are written in ES6, if you want to ensure backwards-compatibility, please use the [Babel transpiler](https://babeljs.io/). +- 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. ## Contents diff --git a/static-parts/README-start.md b/static-parts/README-start.md index b5e4eec03..90b6c6587 100644 --- a/static-parts/README-start.md +++ b/static-parts/README-start.md @@ -4,7 +4,7 @@ > Curated collection of useful Javascript snippets that you can understand in 30 seconds or less. - Use Ctrl + F or command + F to search for a snippet. -- Contributions welcome, please read [contribution guide](CONTRIBUTING.md). -- Snippets are written in ES6, if you want to ensure backwards-compatibility, please use the [Babel transpiler](https://babeljs.io/). +- 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. ## Contents From 911610949818bbd9b27d492bc551baff3506e89d Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 23:00:21 +1100 Subject: [PATCH 054/202] Create standard-deviation.md http://www.calculator.net/standard-deviation-calculator.html As a one-liner it's really long, feel free to optimize the formatting here (or shorten it further somehow). --- snippets/standard-deviation.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 snippets/standard-deviation.md diff --git a/snippets/standard-deviation.md b/snippets/standard-deviation.md new file mode 100644 index 000000000..3ee95a147 --- /dev/null +++ b/snippets/standard-deviation.md @@ -0,0 +1,16 @@ +### Standard deviation + +Use `Array.reduce()` to calculate the mean of the values, the variance of the values, and the sum of the variance +of the values to determine the standard deviation of an array of numbers. + +NOTE: This is **population standard deviation**. Use `/ (arr.length - 1)` at the end to +calculate **sample standard deviation**. + +```js +const standardDeviation = (arr, val) => + Math.sqrt( + arr.reduce((acc, val) => acc.concat(Math.pow(val - arr.reduce((acc, val) => acc + val, 0) / arr.length, 2)), []) + .reduce((acc, val) => acc + val, 0) + / arr.length + ); +``` From 635adbc61799bfb7659448f38099adb496a80b6a Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 23:02:21 +1100 Subject: [PATCH 055/202] Update standard-deviation.md --- snippets/standard-deviation.md | 1 + 1 file changed, 1 insertion(+) diff --git a/snippets/standard-deviation.md b/snippets/standard-deviation.md index 3ee95a147..63485f91e 100644 --- a/snippets/standard-deviation.md +++ b/snippets/standard-deviation.md @@ -13,4 +13,5 @@ const standardDeviation = (arr, val) => .reduce((acc, val) => acc + val, 0) / arr.length ); +// standardDeviation([10,2,38,23,38,23,21]) -> 12.298996142875 ``` From 5522a4c207ca07cc858405b4ca5c657e08c4fead Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 14:09:25 +0200 Subject: [PATCH 056/202] Updated URL parameters --- README.md | 7 ++++--- snippets/URL-parameters.md | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7f583154b..c6bcb3855 100644 --- a/README.md +++ b/README.md @@ -615,13 +615,14 @@ const unique = arr => [...new Set(arr)]; ### URL parameters -Use `match()` with an appropriate regular expression to get all key-value pairs, `map()` them appropriately. -Combine all key-value pairs into a single object using `Object.assign()` and the spread operator (`...`). +Use `match()` with an appropriate regular expression to get all key-value pairs, `Array.reduce()` to map and combine them into a single object. Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => - Object.assign(...url.match(/([^?=&]+)(=([^&]*))?/g).map(m => {[f,v] = m.split('='); return {[f]:v}})); + url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')), a), {} + ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} ``` diff --git a/snippets/URL-parameters.md b/snippets/URL-parameters.md index 4620513dc..42a43cc22 100644 --- a/snippets/URL-parameters.md +++ b/snippets/URL-parameters.md @@ -1,11 +1,12 @@ ### URL parameters -Use `match()` with an appropriate regular expression to get all key-value pairs, `map()` them appropriately. -Combine all key-value pairs into a single object using `Object.assign()` and the spread operator (`...`). +Use `match()` with an appropriate regular expression to get all key-value pairs, `Array.reduce()` to map and combine them into a single object. Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => - Object.assign(...url.match(/([^?=&]+)(=([^&]*))?/g).map(m => {[f,v] = m.split('='); return {[f]:v}})); + url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')), a), {} + ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} ``` From b995e1bea1a7b88f2ed8e130f3423fb4134366a4 Mon Sep 17 00:00:00 2001 From: piyuesh Date: Wed, 13 Dec 2017 17:41:45 +0530 Subject: [PATCH 057/202] prefixed Array. to reduce(), sort(), map() methods in snippets. --- snippets/URL-parameters.md | 2 +- snippets/anagrams-of-string-(with-duplicates).md | 2 +- snippets/average-of-array-of-numbers.md | 2 +- snippets/count-occurrences-of-a-value-in-array.md | 2 +- snippets/deep-flatten-array.md | 2 +- snippets/flatten-array.md | 2 +- snippets/initialize-array-with-range.md | 2 +- snippets/powerset.md | 2 +- snippets/randomize-order-of-array.md | 2 +- snippets/sort-characters-in-string-(alphabetical).md | 2 +- snippets/sum-of-array-of-numbers.md | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/snippets/URL-parameters.md b/snippets/URL-parameters.md index 4620513dc..b3b676931 100644 --- a/snippets/URL-parameters.md +++ b/snippets/URL-parameters.md @@ -1,6 +1,6 @@ ### URL parameters -Use `match()` with an appropriate regular expression to get all key-value pairs, `map()` them appropriately. +Use `match()` with an appropriate regular expression to get all key-value pairs, `Array.map()` them appropriately. Combine all key-value pairs into a single object using `Object.assign()` and the spread operator (`...`). Pass `location.search` as the argument to apply to the current `url`. diff --git a/snippets/anagrams-of-string-(with-duplicates).md b/snippets/anagrams-of-string-(with-duplicates).md index 10b949654..7e1d613b6 100644 --- a/snippets/anagrams-of-string-(with-duplicates).md +++ b/snippets/anagrams-of-string-(with-duplicates).md @@ -2,7 +2,7 @@ Use recursion. For each letter in the given string, create all the partial anagrams for the rest of its letters. -Use `map()` to combine the letter with each partial anagram, then `reduce()` to combine all anagrams in one array. +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 diff --git a/snippets/average-of-array-of-numbers.md b/snippets/average-of-array-of-numbers.md index 615e183b8..8d9aaf1cd 100644 --- a/snippets/average-of-array-of-numbers.md +++ b/snippets/average-of-array-of-numbers.md @@ -1,6 +1,6 @@ ### Average of array of numbers -Use `reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. +Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. ```js const average = arr => diff --git a/snippets/count-occurrences-of-a-value-in-array.md b/snippets/count-occurrences-of-a-value-in-array.md index 89e3b5b6d..f4a0dc210 100644 --- a/snippets/count-occurrences-of-a-value-in-array.md +++ b/snippets/count-occurrences-of-a-value-in-array.md @@ -1,6 +1,6 @@ ### Count occurrences of a value in array -Use `reduce()` to increment a counter each time you encounter the specific value inside the array. +Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. ```js const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); diff --git a/snippets/deep-flatten-array.md b/snippets/deep-flatten-array.md index 472143583..397d62241 100644 --- a/snippets/deep-flatten-array.md +++ b/snippets/deep-flatten-array.md @@ -1,7 +1,7 @@ ### Deep flatten array Use recursion. -Use `reduce()` to get all elements that are not arrays, flatten each element that is an array. +Use `Array.reduce()` to get all elements that are not arrays, flatten each element that is an array. ```js const deepFlatten = arr => diff --git a/snippets/flatten-array.md b/snippets/flatten-array.md index a677fa4ea..224060d02 100644 --- a/snippets/flatten-array.md +++ b/snippets/flatten-array.md @@ -1,6 +1,6 @@ ### Flatten array -Use `reduce()` to get all elements inside the array and `concat()` to flatten them. +Use `Array.reduce()` to get all elements inside the array and `concat()` to flatten them. ```js const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); diff --git a/snippets/initialize-array-with-range.md b/snippets/initialize-array-with-range.md index c974f2786..03de99eb2 100644 --- a/snippets/initialize-array-with-range.md +++ b/snippets/initialize-array-with-range.md @@ -1,6 +1,6 @@ ### Initialize array with range -Use `Array(end-start)` to create an array of the desired length, `map()` to fill with the desired values in a range. +Use `Array(end-start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. You can omit `start` to use a default value of `0`. ```js diff --git a/snippets/powerset.md b/snippets/powerset.md index 2908c78b2..62ec96655 100644 --- a/snippets/powerset.md +++ b/snippets/powerset.md @@ -1,6 +1,6 @@ ### Powerset -Use `reduce()` combined with `map()` to iterate over elements and combine into an array containing all combinations. +Use `Array.reduce()` combined with `Array.map()` to iterate over elements and combine into an array containing all combinations. ```js const powerset = arr => diff --git a/snippets/randomize-order-of-array.md b/snippets/randomize-order-of-array.md index fe9093843..d65aaf444 100644 --- a/snippets/randomize-order-of-array.md +++ b/snippets/randomize-order-of-array.md @@ -1,6 +1,6 @@ ### Randomize order of array -Use `sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. +Use `Array.sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. ```js const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); diff --git a/snippets/sort-characters-in-string-(alphabetical).md b/snippets/sort-characters-in-string-(alphabetical).md index c283ca17c..7ed73cb14 100644 --- a/snippets/sort-characters-in-string-(alphabetical).md +++ b/snippets/sort-characters-in-string-(alphabetical).md @@ -1,6 +1,6 @@ ### Sort characters in string (alphabetical) -Split the string using `split('')`, `sort()` utilizing `localeCompare()`, recombine using `join('')`. +Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, recombine using `join('')`. ```js const sortCharactersInString = str => diff --git a/snippets/sum-of-array-of-numbers.md b/snippets/sum-of-array-of-numbers.md index fcf01949c..939106cc1 100644 --- a/snippets/sum-of-array-of-numbers.md +++ b/snippets/sum-of-array-of-numbers.md @@ -1,6 +1,6 @@ ### Sum of array of numbers -Use `reduce()` to add each value to an accumulator, initialized with a value of `0`. +Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. ```js const sum = arr => arr.reduce( (acc , val) => acc + val, 0); From 731df313959b3b47e4c9ed4da46c9fa941947608 Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 23:12:42 +1100 Subject: [PATCH 058/202] Update standard-deviation.md --- snippets/standard-deviation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/standard-deviation.md b/snippets/standard-deviation.md index 63485f91e..0ae7f56af 100644 --- a/snippets/standard-deviation.md +++ b/snippets/standard-deviation.md @@ -7,7 +7,7 @@ NOTE: This is **population standard deviation**. Use `/ (arr.length - 1)` at the calculate **sample standard deviation**. ```js -const standardDeviation = (arr, val) => +const standardDeviation = arr => Math.sqrt( arr.reduce((acc, val) => acc.concat(Math.pow(val - arr.reduce((acc, val) => acc + val, 0) / arr.length, 2)), []) .reduce((acc, val) => acc + val, 0) From bab7996b3b72178ccdea68b0bc95d14614e50858 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 14:14:04 +0200 Subject: [PATCH 059/202] Update bottom-visible.md --- snippets/bottom-visible.md | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/snippets/bottom-visible.md b/snippets/bottom-visible.md index 403a157f8..9045c6bff 100644 --- a/snippets/bottom-visible.md +++ b/snippets/bottom-visible.md @@ -1,16 +1,9 @@ ### Bottom visible -Returns `true` if bottom of the page is visible. It adds `scrollY` to -the height of the visible portion of the page (`clientHeight`) and -compares it to `pageHeight` to see if bottom of the page is visible. +Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible. ```js -const bottomVisible = () => { - const scrollY = window.scrollY; - const visibleHeight = document.documentElement.clientHeight; - const pageHeight = document.documentElement.scrollHeight; - const bottomOfPage = visibleHeight + scrollY >= pageHeight; - - return bottomOfPage || pageHeight < visibleHeight; -} +const bottomVisible = _ => + document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; +// bottomVisible() -> true ``` From fceabcc75f55d1d7bdfaa3ce6c50a4e29d621d13 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 14:15:07 +0200 Subject: [PATCH 060/202] Build README --- README.md | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5c7bbdd49..d828616ad 100644 --- a/README.md +++ b/README.md @@ -95,19 +95,12 @@ const average = arr => ### Bottom visible -Returns `true` if bottom of the page is visible. It adds `scrollY` to -the height of the visible portion of the page (`clientHeight`) and -compares it to `pageHeight` to see if bottom of the page is visible. +Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible. ```js -const bottomVisible = () => { - const scrollY = window.scrollY; - const visibleHeight = document.documentElement.clientHeight; - const pageHeight = document.documentElement.scrollHeight; - const bottomOfPage = visibleHeight + scrollY >= pageHeight; - - return bottomOfPage || pageHeight < visibleHeight; -} +const bottomVisible = _ => + document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; +// bottomVisible() -> true ``` ### Capitalize first letter of every word From babb858ce2ce41cb876c802d0afdfec0b0a4b4d1 Mon Sep 17 00:00:00 2001 From: Daniel Ramos Date: Wed, 13 Dec 2017 12:15:39 +0000 Subject: [PATCH 061/202] Moving semicolon, changing example in promisify.md --- snippets/promisify.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/snippets/promisify.md b/snippets/promisify.md index d6b437589..f9516aeed 100644 --- a/snippets/promisify.md +++ b/snippets/promisify.md @@ -1,15 +1,14 @@ ### Promisify -Creates a promisified version of the given callback-style function. 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. In Node 8+, you can use [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original) ```js const promisify = func => (...args) => new Promise((resolve, reject) => func(...args, (err, result) => - err ? reject(err) : resolve(result)); - ) -// const stat = promisify(fs.stat) -// stat('foo.txt') -> Promise resolves if `foo.txt` exists, otherwise rejects + err ? reject(err) : resolve(result)) + ); +// const delay = promisify((d, cb) => setTimeout(cb, d)) +// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s ``` From 36bff4628dd72f6f4416e3762a80da2f72b3dcde Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 14:17:24 +0200 Subject: [PATCH 062/202] Update promisify.md --- snippets/promisify.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/snippets/promisify.md b/snippets/promisify.md index f9516aeed..bdedec054 100644 --- a/snippets/promisify.md +++ b/snippets/promisify.md @@ -1,6 +1,9 @@ ### Promisify -Use currying to return a function returning a Promise that calls the original function. Use the rest operator to pass in all the parameters. 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. + +*In Node 8+, you can use [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original)* ```js const promisify = func => From 43b15538caacb48520876be39b6203a1b265a270 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 14:18:52 +0200 Subject: [PATCH 063/202] Build README --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3ca38fa97..9b81f83ee 100644 --- a/README.md +++ b/README.md @@ -464,20 +464,20 @@ const powerset = arr => ### Promisify -Creates a promisified version of the given callback-style function. 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. + +*In Node 8+, you can use [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original)* ```js const promisify = func => (...args) => new Promise((resolve, reject) => func(...args, (err, result) => - err - ? reject(err) - : resolve(result)) - ) -// const stat = promisify(fs.stat) -// stat('foo.txt') -> Promise resolves if `foo.txt` exists, otherwise rejects + err ? reject(err) : resolve(result)) + ); +// const delay = promisify((d, cb) => setTimeout(cb, d)) +// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s ``` ### Random integer in range From 44ffb6d0b34e1d38caf9b138a18f260728761668 Mon Sep 17 00:00:00 2001 From: Pritesh Poddar Date: Wed, 13 Dec 2017 17:49:35 +0530 Subject: [PATCH 064/202] hamming distance between two numbers --- snippets/hamming-distance.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 snippets/hamming-distance.md diff --git a/snippets/hamming-distance.md b/snippets/hamming-distance.md new file mode 100644 index 000000000..3c8669d4a --- /dev/null +++ b/snippets/hamming-distance.md @@ -0,0 +1,10 @@ +### Hamming distance between two numbers + +Use XOR operator. +Find the binary bit difference between two number using `^` operator.Convert the result to binary string using `toString(2)`.Get the difference by getting the number of 1's in the binary digit using `match(/1/g)`. +```js +const hammingDistance = (num1, num2) => { + return ((num1^num2).toString(2).match(/1/g) || '').length; +} +//hammingDistance(2,3) -> 1 +``` From 5781466314c1c746fa34ac2d7c10355dd8500780 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 14:23:56 +0200 Subject: [PATCH 065/202] Update hamming-distance.md --- snippets/hamming-distance.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/snippets/hamming-distance.md b/snippets/hamming-distance.md index 3c8669d4a..f4ddc1eec 100644 --- a/snippets/hamming-distance.md +++ b/snippets/hamming-distance.md @@ -1,10 +1,9 @@ ### Hamming distance between two numbers -Use XOR operator. -Find the binary bit difference between two number using `^` operator.Convert the result to binary string using `toString(2)`.Get the difference by getting the number of 1's in the binary digit using `match(/1/g)`. +Use XOR operator (`^`) to find the bit difference between the two numbers, convert to binary string using `toString(2)`. +Count and return the number of `1`s in the string, using `match(/1/g)`. ```js -const hammingDistance = (num1, num2) => { - return ((num1^num2).toString(2).match(/1/g) || '').length; -} +const hammingDistance = (num1, num2) => + ((num1^num2).toString(2).match(/1/g) || '').length; //hammingDistance(2,3) -> 1 ``` From 634faf639399fb5c0125a61747048f83c5c7995b Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 14:24:57 +0200 Subject: [PATCH 066/202] Build README --- README.md | 12 ++++++++++++ snippets/hamming-distance.md | 7 ++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9b81f83ee..223950ba3 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ * [Get native type of value](#get-native-type-of-value) * [Get scroll position](#get-scroll-position) * [Greatest common divisor (GCD)](#greatest-common-divisor-gcd) +* [Hamming distance](#hamming-distance) * [Head of list](#head-of-list) * [Initial of list](#initial-of-list) * [Initialize array with range](#initialize-array-with-range) @@ -347,6 +348,17 @@ const gcd = (x , y) => !y ? x : gcd(y, x % y); // gcd (8, 36) -> 4 ``` +### Hamming distance + +Use XOR operator (`^`) to find the bit difference between the two numbers, convert to binary string using `toString(2)`. +Count and return the number of `1`s in the string, using `match(/1/g)`. + +```js +const hammingDistance = (num1, num2) => + ((num1^num2).toString(2).match(/1/g) || '').length; +// hammingDistance(2,3) -> 1 +``` + ### Head of list Return `arr[0]`. diff --git a/snippets/hamming-distance.md b/snippets/hamming-distance.md index f4ddc1eec..5b47db022 100644 --- a/snippets/hamming-distance.md +++ b/snippets/hamming-distance.md @@ -1,9 +1,10 @@ -### Hamming distance between two numbers +### Hamming distance Use XOR operator (`^`) to find the bit difference between the two numbers, convert to binary string using `toString(2)`. Count and return the number of `1`s in the string, using `match(/1/g)`. + ```js -const hammingDistance = (num1, num2) => +const hammingDistance = (num1, num2) => ((num1^num2).toString(2).match(/1/g) || '').length; -//hammingDistance(2,3) -> 1 +// hammingDistance(2,3) -> 1 ``` From b844b0f765dbdb69783d544a39f067bb708f8744 Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 23:41:28 +1100 Subject: [PATCH 067/202] Add usePopulation flag param --- snippets/standard-deviation.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/snippets/standard-deviation.md b/snippets/standard-deviation.md index 0ae7f56af..a2b9a64fe 100644 --- a/snippets/standard-deviation.md +++ b/snippets/standard-deviation.md @@ -3,15 +3,15 @@ Use `Array.reduce()` to calculate the mean of the values, the variance of the values, and the sum of the variance of the values to determine the standard deviation of an array of numbers. -NOTE: This is **population standard deviation**. Use `/ (arr.length - 1)` at the end to -calculate **sample standard deviation**. +Since there are two types of standard deviation, population and sample, you can use a flag to switch to population (sample is default). ```js -const standardDeviation = arr => +const standardDeviation = (arr, usePopulation) => Math.sqrt( arr.reduce((acc, val) => acc.concat(Math.pow(val - arr.reduce((acc, val) => acc + val, 0) / arr.length, 2)), []) .reduce((acc, val) => acc + val, 0) - / arr.length + / (arr.length - (usePopulation ? 0 : 1)) ); -// standardDeviation([10,2,38,23,38,23,21]) -> 12.298996142875 +// standardDeviation([10,2,38,23,38,23,21]) -> 13.284434142114991 (sample) +// standardDeviation([10,2,38,23,38,23,21], true) -> 12.29899614287479 (population) ``` From 3d7b322a9d9defaf99a3f3f27aec45857697156f Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 23:48:29 +1100 Subject: [PATCH 068/202] Cache the mean --- snippets/standard-deviation.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/snippets/standard-deviation.md b/snippets/standard-deviation.md index a2b9a64fe..b1dd0b9c6 100644 --- a/snippets/standard-deviation.md +++ b/snippets/standard-deviation.md @@ -6,12 +6,14 @@ of the values to determine the standard deviation of an array of numbers. Since there are two types of standard deviation, population and sample, you can use a flag to switch to population (sample is default). ```js -const standardDeviation = (arr, usePopulation) => - Math.sqrt( - arr.reduce((acc, val) => acc.concat(Math.pow(val - arr.reduce((acc, val) => acc + val, 0) / arr.length, 2)), []) +const standardDeviation = (arr, usePopulation) => { + const mean = arr.reduce((acc, val) => acc + val, 0); + return Math.sqrt( + arr.reduce((acc, val) => acc.concat(Math.pow(val - mean / arr.length, 2)), []) .reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1)) ); + } // standardDeviation([10,2,38,23,38,23,21]) -> 13.284434142114991 (sample) // standardDeviation([10,2,38,23,38,23,21], true) -> 12.29899614287479 (population) ``` From c876845318b9b59982a0ef62846e976f0c2b5aed Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 14:48:38 +0200 Subject: [PATCH 069/202] Update URL-parameters.md Updated a file that was changed in the meantime --- snippets/URL-parameters.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/snippets/URL-parameters.md b/snippets/URL-parameters.md index 17daf16f0..42a43cc22 100644 --- a/snippets/URL-parameters.md +++ b/snippets/URL-parameters.md @@ -1,7 +1,6 @@ ### URL parameters -Use `match()` with an appropriate regular expression to get all key-value pairs, `Array.map()` them appropriately. -Combine all key-value pairs into a single object using `Object.assign()` and the spread operator (`...`). +Use `match()` with an appropriate regular expression to get all key-value pairs, `Array.reduce()` to map and combine them into a single object. Pass `location.search` as the argument to apply to the current `url`. ```js From e0e98be0fc37254e0e23a73ad946365cc2cfcd7a Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 14:49:56 +0200 Subject: [PATCH 070/202] Build README, resolve #62 --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 223950ba3..80a3baec4 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Use recursion. For each letter in the given string, create all the partial anagrams for the rest of its letters. -Use `map()` to combine the letter with each partial anagram, then `reduce()` to combine all anagrams in one array. +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 @@ -87,7 +87,7 @@ const anagrams = str => { ### Average of array of numbers -Use `reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. +Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. ```js const average = arr => @@ -165,7 +165,7 @@ const chunk = (arr, size) => ### Count occurrences of a value in array -Use `reduce()` to increment a counter each time you encounter the specific value inside the array. +Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. ```js const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); @@ -203,7 +203,7 @@ const curry = (f, arity = f.length, next) => ### Deep flatten array Use recursion. -Use `reduce()` to get all elements that are not arrays, flatten each element that is an array. +Use `Array.reduce()` to get all elements that are not arrays, flatten each element that is an array. ```js const deepFlatten = arr => @@ -290,7 +290,7 @@ const unique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); ### Flatten array -Use `reduce()` to get all elements inside the array and `concat()` to flatten them. +Use `Array.reduce()` to get all elements inside the array and `concat()` to flatten them. ```js const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); @@ -379,7 +379,7 @@ const initial = arr => arr.slice(0,-1); ### Initialize array with range -Use `Array(end-start)` to create an array of the desired length, `map()` to fill with the desired values in a range. +Use `Array(end-start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. You can omit `start` to use a default value of `0`. ```js @@ -466,7 +466,7 @@ const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg); ### Powerset -Use `reduce()` combined with `map()` to iterate over elements and combine into an array containing all combinations. +Use `Array.reduce()` combined with `Array.map()` to iterate over elements and combine into an array containing all combinations. ```js const powerset = arr => @@ -512,7 +512,7 @@ const randomInRange = (min, max) => Math.random() * (max - min) + min; ### Randomize order of array -Use `sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. +Use `Array.sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. ```js const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); @@ -599,7 +599,7 @@ const similarity = (arr, values) => arr.filter(v => values.includes(v)); ### Sort characters in string (alphabetical) -Split the string using `split('')`, `sort()` utilizing `localeCompare()`, recombine using `join('')`. +Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, recombine using `join('')`. ```js const sortCharactersInString = str => @@ -609,7 +609,7 @@ const sortCharactersInString = str => ### Sum of array of numbers -Use `reduce()` to add each value to an accumulator, initialized with a value of `0`. +Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. ```js const sum = arr => arr.reduce( (acc , val) => acc + val, 0); From 418069551b528e3855d2a39a6375f70a88b36a2e Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 23:54:33 +1100 Subject: [PATCH 071/202] Update standard-deviation.md --- snippets/standard-deviation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/standard-deviation.md b/snippets/standard-deviation.md index b1dd0b9c6..3641cbe14 100644 --- a/snippets/standard-deviation.md +++ b/snippets/standard-deviation.md @@ -7,7 +7,7 @@ Since there are two types of standard deviation, population and sample, you can ```js const standardDeviation = (arr, usePopulation) => { - const mean = arr.reduce((acc, val) => acc + val, 0); + const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; return Math.sqrt( arr.reduce((acc, val) => acc.concat(Math.pow(val - mean / arr.length, 2)), []) .reduce((acc, val) => acc + val, 0) From 98f56cbf2394b59053f14b4e4ef382c456965128 Mon Sep 17 00:00:00 2001 From: atomiks Date: Wed, 13 Dec 2017 23:55:08 +1100 Subject: [PATCH 072/202] Update standard-deviation.md --- snippets/standard-deviation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/standard-deviation.md b/snippets/standard-deviation.md index 3641cbe14..442052761 100644 --- a/snippets/standard-deviation.md +++ b/snippets/standard-deviation.md @@ -9,7 +9,7 @@ Since there are two types of standard deviation, population and sample, you can const standardDeviation = (arr, usePopulation) => { const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; return Math.sqrt( - arr.reduce((acc, val) => acc.concat(Math.pow(val - mean / arr.length, 2)), []) + arr.reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) .reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1)) ); From 8b9483a23b8d75da69501866e241224405a4c27a Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 15:29:01 +0200 Subject: [PATCH 073/202] Add gitter badge --- README.md | 2 +- static-parts/README-start.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 80a3baec4..4b3facb00 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![Logo](/logo.png) -# 30 seconds of code +# 30 seconds of code [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/30-seconds-of-code/Lobby) > Curated collection of useful Javascript snippets that you can understand in 30 seconds or less. - Use Ctrl + F or command + F to search for a snippet. diff --git a/static-parts/README-start.md b/static-parts/README-start.md index 90b6c6587..1bfdbba0e 100644 --- a/static-parts/README-start.md +++ b/static-parts/README-start.md @@ -1,6 +1,6 @@ ![Logo](/logo.png) -# 30 seconds of code +# 30 seconds of code [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/30-seconds-of-code/Lobby) > Curated collection of useful Javascript snippets that you can understand in 30 seconds or less. - Use Ctrl + F or command + F to search for a snippet. From ce786721d5978707f921eed13d02d2a987b3be32 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 15:37:32 +0200 Subject: [PATCH 074/202] Fixed LICENSE, again --- LICENSE | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 4 deletions(-) diff --git a/LICENSE b/LICENSE index 9eea76289..670154e35 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,116 @@ -30 seconds of code is licensed under Creative Commons CC0 1.0 Universal license. -https://creativecommons.org/publicdomain/zero/1.0/ -The license states, "You can copy, modify, distribute and perform the work, even for commercial purposes, -all without asking permission." Additionally, we ask that groups utilizing this ontology reference this project. +CC0 1.0 Universal + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator and +subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for the +purpose of contributing to a commons of creative, cultural and scientific +works ("Commons") that the public can reliably and without fear of later +claims of infringement build upon, modify, incorporate in other works, reuse +and redistribute as freely as possible in any form whatsoever and for any +purposes, including without limitation commercial purposes. These owners may +contribute to the Commons to promote the ideal of a free culture and the +further production of creative, cultural and scientific works, or to gain +reputation or greater distribution for their Work in part through the use and +efforts of others. + +For these and/or other purposes and motivations, and without any expectation +of additional consideration or compensation, the person associating CC0 with a +Work (the "Affirmer"), to the extent that he or she is an owner of Copyright +and Related Rights in the Work, voluntarily elects to apply CC0 to the Work +and publicly distribute the Work under its terms, with knowledge of his or her +Copyright and Related Rights in the Work and the meaning and intended legal +effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not limited +to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, communicate, + and translate a Work; + + ii. moral rights retained by the original author(s) and/or performer(s); + + iii. publicity and privacy rights pertaining to a person's image or likeness + depicted in a Work; + + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + + v. rights protecting the extraction, dissemination, use and reuse of data in + a Work; + + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation thereof, + including any amended or successor version of such directive); and + + vii. other similar, equivalent or corresponding rights throughout the world + based on applicable law or treaty, and any national implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention of, +applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and +unconditionally waives, abandons, and surrenders all of Affirmer's Copyright +and Related Rights and associated claims and causes of action, whether now +known or unknown (including existing as well as future claims and causes of +action), in the Work (i) in all territories worldwide, (ii) for the maximum +duration provided by applicable law or treaty (including future time +extensions), (iii) in any current or future medium and for any number of +copies, and (iv) for any purpose whatsoever, including without limitation +commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes +the Waiver for the benefit of each member of the public at large and to the +detriment of Affirmer's heirs and successors, fully intending that such Waiver +shall not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of the Work +by the public as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason be +judged legally invalid or ineffective under applicable law, then the Waiver +shall be preserved to the maximum extent permitted taking into account +Affirmer's express Statement of Purpose. In addition, to the extent the Waiver +is so judged Affirmer hereby grants to each affected person a royalty-free, +non transferable, non sublicensable, non exclusive, irrevocable and +unconditional license to exercise Affirmer's Copyright and Related Rights in +the Work (i) in all territories worldwide, (ii) for the maximum duration +provided by applicable law or treaty (including future time extensions), (iii) +in any current or future medium and for any number of copies, and (iv) for any +purpose whatsoever, including without limitation commercial, advertising or +promotional purposes (the "License"). The License shall be deemed effective as +of the date CC0 was applied by Affirmer to the Work. Should any part of the +License for any reason be judged legally invalid or ineffective under +applicable law, such partial invalidity or ineffectiveness shall not +invalidate the remainder of the License, and in such case Affirmer hereby +affirms that he or she will not (i) exercise any of his or her remaining +Copyright and Related Rights in the Work or (ii) assert any associated claims +and causes of action with respect to the Work, in either case contrary to +Affirmer's express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + + b. Affirmer offers the Work as-is and makes no representations or warranties + of any kind concerning the Work, express, implied, statutory or otherwise, + including without limitation warranties of title, merchantability, fitness + for a particular purpose, non infringement, or the absence of latent or + other defects, accuracy, or the present or absence of errors, whether or not + discoverable, all to the greatest extent permissible under applicable law. + + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without limitation + any person's Copyright and Related Rights in the Work. Further, Affirmer + disclaims responsibility for obtaining any necessary consents, permissions + or other rights required for any use of the Work. + + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to this + CC0 or use of the Work. + +For more information, please see + From 54f163b9f105a82a6b225a274cc7a96ceb7b4553 Mon Sep 17 00:00:00 2001 From: Michael Goldspinner Date: Wed, 13 Dec 2017 09:01:14 -0500 Subject: [PATCH 075/202] Get Ordinal Suffix of Number JS Code Snippet to get the ordinal suffix of a given number (int or string). Returns the provided value wtih concatenated ordinal. --- snippets/get-ordinal-suffix-of-number.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 snippets/get-ordinal-suffix-of-number.md diff --git a/snippets/get-ordinal-suffix-of-number.md b/snippets/get-ordinal-suffix-of-number.md new file mode 100644 index 000000000..cda41b9ac --- /dev/null +++ b/snippets/get-ordinal-suffix-of-number.md @@ -0,0 +1,18 @@ +### Get Ordinal Suffix of Number + +Use the modulo operator (`%`) to find values of single and tens digits. +Find which ordinal pattern digits match. +If digit is found in teens pattern, use teens ordinal. + +```js +const toOrdinalSuffix = int => { + int = parseInt(int); + var digits = [ (int % 10), (int % 100)]; + var ordinals = ["st", "nd", "rd", "th"]; + var oPattern = [1,2,3,4]; + var tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] + + return pattern.includes(digits[0]) && !teens.includes(digits[1]) ? int + suffix[digits[0]-1] : int + suffix[3]; +} +// toOrdinalSuffix("123") -> "123rd" +``` \ No newline at end of file From 42237471ab4a6c9d6b63a6fbf7f87072e2ad91c0 Mon Sep 17 00:00:00 2001 From: Meet Zaveri Date: Wed, 13 Dec 2017 21:42:58 +0530 Subject: [PATCH 076/202] Create join_array_like_objects.md --- snippets/join_array_like_objects.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 snippets/join_array_like_objects.md diff --git a/snippets/join_array_like_objects.md b/snippets/join_array_like_objects.md new file mode 100644 index 000000000..57acd6731 --- /dev/null +++ b/snippets/join_array_like_objects.md @@ -0,0 +1,11 @@ +### Joining an array-like object + +The following example joins array-like object (arguments), by calling Function.prototype.call on Array.prototype.join. + +``` +function f(a, b, c) { + var s = Array.prototype.join.call(arguments); + console.log(s); // '1,a,true' +} +f(1, 'a', true); +``` From 8f839542b61a6bb0188146c3f06be68a169c742d Mon Sep 17 00:00:00 2001 From: Meet Zaveri Date: Wed, 13 Dec 2017 21:52:51 +0530 Subject: [PATCH 077/202] Create check_for_boolean --- snippets/check_for_boolean | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 snippets/check_for_boolean diff --git a/snippets/check_for_boolean b/snippets/check_for_boolean new file mode 100644 index 000000000..a96719aea --- /dev/null +++ b/snippets/check_for_boolean @@ -0,0 +1,10 @@ +### Check for Boolean Primitive Values + +Check if a value is classified as a boolean primitive. Return true or false. + +function booWho(bool) { + return typeof bool === 'boolean'; +} + +// test here +booWho(null); From e82141f80155f30f0a503a0d6e66db05cee9d241 Mon Sep 17 00:00:00 2001 From: Meet Zaveri Date: Wed, 13 Dec 2017 21:56:13 +0530 Subject: [PATCH 078/202] Rename check_for_boolean to check_for_boolean.md --- snippets/{check_for_boolean => check_for_boolean.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename snippets/{check_for_boolean => check_for_boolean.md} (100%) diff --git a/snippets/check_for_boolean b/snippets/check_for_boolean.md similarity index 100% rename from snippets/check_for_boolean rename to snippets/check_for_boolean.md From 32c27187a450d240b39cffb3af2b782431d47165 Mon Sep 17 00:00:00 2001 From: Meet Zaveri Date: Wed, 13 Dec 2017 22:00:06 +0530 Subject: [PATCH 079/202] Create drop_elements_in_array.md --- snippets/drop_elements_in_array.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 snippets/drop_elements_in_array.md diff --git a/snippets/drop_elements_in_array.md b/snippets/drop_elements_in_array.md new file mode 100644 index 000000000..73e2688b5 --- /dev/null +++ b/snippets/drop_elements_in_array.md @@ -0,0 +1,19 @@ +### Drop It + +Drop the elements of an array (first argument), starting from the front, until the predicate (second argument) returns true. + +Method - +- Use a while loop with Array.prototype.shift() to continue checking and dropping the first element of the array until the function returns true. It also makes sure the array is not empty first to avoid infinite loops. +- Return the filtered array. + +``` +function dropElements(arr, func) { + while(arr.length > 0 && !func(arr[0])) { + arr.shift(); + } + return arr; +} + +// test here +dropElements([1, 2, 3, 4], function(n) {return n >= 3;}); +``` From afddb68d4f536999640bc8fc4833559d1aaea7c5 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 20:02:19 +0200 Subject: [PATCH 080/202] Fix URL params, resolve #74 --- README.md | 2 +- snippets/URL-parameters.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4b3facb00..dddd5b9e3 100644 --- a/README.md +++ b/README.md @@ -663,7 +663,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => url.match(/([^?=&]+)(=([^&]*))?/g).reduce( - (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')), a), {} + (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')+1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} ``` diff --git a/snippets/URL-parameters.md b/snippets/URL-parameters.md index 42a43cc22..c5a316b76 100644 --- a/snippets/URL-parameters.md +++ b/snippets/URL-parameters.md @@ -6,7 +6,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => url.match(/([^?=&]+)(=([^&]*))?/g).reduce( - (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')), a), {} + (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')+1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} ``` From 35f81c10f23715cbce02e3ef99736c936283ee1c Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 20:57:32 +0200 Subject: [PATCH 081/202] Consistency for snippet highlighting --- README.md | 4 ++-- snippets/truncate-a-string.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dddd5b9e3..adb6cf6db 100644 --- a/README.md +++ b/README.md @@ -637,10 +637,10 @@ const tail = arr => arr.length > 1 ? arr.slice(1) : arr; ### Truncate a String -Determine if the string's `length` is greater than `num`. +Determine if the string's `length` is greater than `num`. Return the string truncated to the desired length, with `...` appended to the end or the original string. -``` +```js const truncate = (str, num) => str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; // truncate('boomerang', 7) -> 'boom...' diff --git a/snippets/truncate-a-string.md b/snippets/truncate-a-string.md index 5c2a091cb..556667781 100644 --- a/snippets/truncate-a-string.md +++ b/snippets/truncate-a-string.md @@ -1,9 +1,9 @@ ### Truncate a String -Determine if the string's `length` is greater than `num`. +Determine if the string's `length` is greater than `num`. Return the string truncated to the desired length, with `...` appended to the end or the original string. -``` +```js const truncate = (str, num) => str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; // truncate('boomerang', 7) -> 'boom...' From 3a9c322d138676367d8ca05d237d5630a3fa64cb Mon Sep 17 00:00:00 2001 From: Adrian Klimek Date: Wed, 13 Dec 2017 20:02:29 +0100 Subject: [PATCH 082/202] Build the list --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 93fbac389..12212b820 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); ### Even or odd number -Checks whether number is odd or even using the modulo (`%`) operator. +Checks whether a number is odd or even using the modulo (`%`) operator. Returns `true` if the number is even, `false` if the number is odd. ```js From 2674273efc6f6123a0e335190882b28dfe7f5097 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Wed, 13 Dec 2017 21:19:39 +0200 Subject: [PATCH 083/202] Naming conflict resolved --- README.md | 4 ++-- snippets/filter-out-non-unique-values-in-an-array.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index adb6cf6db..b77013e78 100644 --- a/README.md +++ b/README.md @@ -284,8 +284,8 @@ const fibonacci = n => Use `Array.filter()` for an array containing only the unique values. ```js -const unique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); -// unique([1,2,2,3,4,4,5]) -> [1,3,5] +const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); +// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] ``` ### Flatten array diff --git a/snippets/filter-out-non-unique-values-in-an-array.md b/snippets/filter-out-non-unique-values-in-an-array.md index 622026234..86562feb4 100644 --- a/snippets/filter-out-non-unique-values-in-an-array.md +++ b/snippets/filter-out-non-unique-values-in-an-array.md @@ -3,6 +3,6 @@ Use `Array.filter()` for an array containing only the unique values. ```js -const unique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); -// unique([1,2,2,3,4,4,5]) -> [1,3,5] +const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); +// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] ``` From e8d9acae9a3d9dd07a4e06716ceb63a2dc137a37 Mon Sep 17 00:00:00 2001 From: Elder Henrique Souza Date: Wed, 13 Dec 2017 18:49:12 -0200 Subject: [PATCH 084/202] group by Tried to reproduce the groupBy behaviour from the lodash lib. https://lodash.com/docs/4.17.4#groupBy --- snippets/group-by | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 snippets/group-by diff --git a/snippets/group-by b/snippets/group-by new file mode 100644 index 000000000..53383db3a --- /dev/null +++ b/snippets/group-by @@ -0,0 +1,16 @@ +### Group by + +Passing an array of values, a function or a property name thats going to be run against each value in the array, +returns an object where the keys are the mapped results and the values is an array of the original values that generated the same results. + +```js +const groupBy = (values, fn) => { + return (typeof fn === 'function' ? values.map(fn) : values.map((val) => val[fn])) + .reduce((acc, val, i) => { + acc[val] = acc[val] === undefined ? [values[i]] : acc[val].concat(values[i]); + return acc; + }, {}); +} +// groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]} +// groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} +``` From b2d737bec5cb1f0e9242d0fdcb87d3ed7c0a2d67 Mon Sep 17 00:00:00 2001 From: King Date: Wed, 13 Dec 2017 16:51:34 -0500 Subject: [PATCH 085/202] add pick code snippiet --- snippets/pick.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 snippets/pick.md diff --git a/snippets/pick.md b/snippets/pick.md new file mode 100644 index 000000000..5523e1fe5 --- /dev/null +++ b/snippets/pick.md @@ -0,0 +1,23 @@ +### Pick + +Use `Objexts.keys()` to convert given object to an iterable arr of keys. +Use `.filter()` to filter the given arr of keys to the expected arr of picked keys. +Use `.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair. + +```js +const pick = (obj, arr) => + Object + .keys(obj) + .filter((v, i) => arr.indexOf(v) !== -1 ) + .reduce((acc, cur, i) => { + acc[cur] = obj[cur]; + return acc; + }, {}); + +// const object = { 'a': 1, 'b': '2', 'c': 3 }; +// pick(object, ['a', 'c']) -> { 'a': 1, 'c': 3 } + +// pick(object, ['a', 'c'])['a'] -> 1 +// pick(object, ['a', 'c'])['c'] -> 3 + +``` \ No newline at end of file From 8c6059098d19e25d8b415180848af40e4c648bdb Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Wed, 13 Dec 2017 22:56:36 +0100 Subject: [PATCH 086/202] Remove duplicate snippets. Simplify implementation --- README.md | 24 +++++------------------- snippets/randomize-order-of-array.md | 8 -------- snippets/shuffle-array-values.md | 12 ------------ snippets/shuffle-array.md | 8 ++++++++ 4 files changed, 13 insertions(+), 39 deletions(-) delete mode 100644 snippets/randomize-order-of-array.md delete mode 100644 snippets/shuffle-array-values.md create mode 100644 snippets/shuffle-array.md diff --git a/README.md b/README.md index b77013e78..7317a259d 100644 --- a/README.md +++ b/README.md @@ -50,13 +50,12 @@ * [Promisify](#promisify) * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) -* [Randomize order of array](#randomize-order-of-array) * [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) * [Scroll to top](#scroll-to-top) -* [Shuffle array values](#shuffle-array-values) +* [Shuffle array](#shuffle-array) * [Similarity between arrays](#similarity-between-arrays) * [Sort characters in string (alphabetical)](#sort-characters-in-string-alphabetical) * [Sum of array of numbers](#sum-of-array-of-numbers) @@ -510,15 +509,6 @@ const randomInRange = (min, max) => Math.random() * (max - min) + min; // randomInRange(2,10) -> 6.0211363285087005 ``` -### Randomize order of array - -Use `Array.sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. - -```js -const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); -// randomizeOrder([1,2,3]) -> [1,3,2] -``` - ### Redirect to URL Use `window.location.href` or `window.location.replace()` to redirect to `url`. @@ -575,17 +565,13 @@ const scrollToTop = _ => { // scrollToTop() ``` -### Shuffle array values +### Shuffle array -Create an array of random values by using `Array.map()` and `Math.random()`. -Use `Array.sort()` to sort the elements of the original array based on the random values. +Use `Array.sort()` to reorder elements, using `Math.random()` in the comparator. ```js -const shuffle = arr => { - let r = arr.map(Math.random); - return arr.sort((a,b) => r[a] - r[b]); -} -// shuffle([1,2,3]) -> [2, 1, 3] +const shuffle = arr => arr.sort(() => Math.random() - 0.5); +// shuffle([1,2,3]) -> [2,3,1] ``` ### Similarity between arrays diff --git a/snippets/randomize-order-of-array.md b/snippets/randomize-order-of-array.md deleted file mode 100644 index d65aaf444..000000000 --- a/snippets/randomize-order-of-array.md +++ /dev/null @@ -1,8 +0,0 @@ -### Randomize order of array - -Use `Array.sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. - -```js -const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); -// randomizeOrder([1,2,3]) -> [1,3,2] -``` diff --git a/snippets/shuffle-array-values.md b/snippets/shuffle-array-values.md deleted file mode 100644 index a140bd647..000000000 --- a/snippets/shuffle-array-values.md +++ /dev/null @@ -1,12 +0,0 @@ -### Shuffle array values - -Create an array of random values by using `Array.map()` and `Math.random()`. -Use `Array.sort()` to sort the elements of the original array based on the random values. - -```js -const shuffle = arr => { - let r = arr.map(Math.random); - return arr.sort((a,b) => r[a] - r[b]); -} -// shuffle([1,2,3]) -> [2, 1, 3] -``` diff --git a/snippets/shuffle-array.md b/snippets/shuffle-array.md new file mode 100644 index 000000000..6266f9ecf --- /dev/null +++ b/snippets/shuffle-array.md @@ -0,0 +1,8 @@ +### Shuffle array + +Use `Array.sort()` to reorder elements, using `Math.random()` in the comparator. + +```js +const shuffle = arr => arr.sort(() => Math.random() - 0.5); +// shuffle([1,2,3]) -> [2,3,1] +``` From f92c6d4079c898ea5a9fa8f6b93d854a58234aaa Mon Sep 17 00:00:00 2001 From: Christian Bender Date: Wed, 13 Dec 2017 23:02:42 +0100 Subject: [PATCH 087/202] collatz algorithm collatz algorithm as function --- snippets/collatz.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 snippets/collatz.md diff --git a/snippets/collatz.md b/snippets/collatz.md new file mode 100644 index 000000000..120f96e27 --- /dev/null +++ b/snippets/collatz.md @@ -0,0 +1,11 @@ +### Collatz algorithm + +If n even then returns **n/2** otherwise (n is odd) **3n+1**. +It uses the ternary operator. + +``` javascript + const collatz = n => (n % 2 == 0) ? (n/2) : (3*n+1); + // collatz(8) --> 4 + // collatz(5) --> 16 + +``` \ No newline at end of file From bf855e55e228991e864adc245504099df8342699 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 00:05:44 +0200 Subject: [PATCH 088/202] Added linting, processed current snippets --- README.md | 75 +- currentSnippet.js | 3 + package-lock.json | 1421 +++++++++++++++++ package.json | 4 +- scripts/builder.js | 4 + scripts/lintSnippet.js | 31 + semi-snippets.js | 242 +++ snippets.js | 302 ++++ snippets/URL-parameters.md | 2 +- snippets/UUID-generator.md | 2 +- .../anagrams-of-string-(with-duplicates).md | 8 +- snippets/average-of-array-of-numbers.md | 3 +- snippets/bottom-visible.md | 2 +- snippets/capitalize-first-letter.md | 2 +- snippets/chain-asynchronous-functions.md | 2 +- snippets/chunk-array.md | 2 +- snippets/deep-flatten-array.md | 2 +- snippets/fibonacci-array-generator.md | 4 +- snippets/flatten-array.md | 2 +- snippets/get-native-type-of-value.md | 2 +- snippets/get-scroll-position.md | 4 +- snippets/greatest-common-divisor-(GCD).md | 2 +- snippets/hamming-distance.md | 2 +- snippets/initial-of-list.md | 2 +- snippets/initialize-array-with-range.md | 2 +- snippets/measure-time-taken-by-function.md | 2 +- snippets/median-of-array-of-numbers.md | 4 +- snippets/object-from-key-value-pairs.md | 2 +- snippets/powerset.md | 2 +- snippets/randomize-order-of-array.md | 2 +- snippets/scroll-to-top.md | 6 +- snippets/shuffle-array-values.md | 4 +- ...ort-characters-in-string-(alphabetical).md | 2 +- snippets/sum-of-array-of-numbers.md | 2 +- snippets/truncate-a-string.md | 2 +- 35 files changed, 2079 insertions(+), 76 deletions(-) create mode 100644 currentSnippet.js create mode 100644 scripts/lintSnippet.js create mode 100644 semi-snippets.js create mode 100644 snippets.js diff --git a/README.md b/README.md index b77013e78..52a314f15 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -78,10 +78,10 @@ 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 )), []); -} + 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)), []); +}; // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` @@ -90,8 +90,7 @@ const anagrams = str => { Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. ```js -const average = arr => - arr.reduce( (acc , val) => acc + val, 0) / arr.length; +const average = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length; // average([1,2,3]) -> 2 ``` @@ -100,7 +99,7 @@ const average = arr => Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible. ```js -const bottomVisible = _ => +const bottomVisible = _ => document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; // bottomVisible() -> true ``` @@ -121,7 +120,7 @@ Omit the `lowerRest` parameter to keep the rest of the string intact, or set it ```js const capitalize = (str, lowerRest = false) => - str.slice(0, 1).toUpperCase() + (lowerRest? str.slice(1).toLowerCase() : str.slice(1)); + str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); // capitalize('myName', true) -> 'Myname' ``` @@ -130,7 +129,7 @@ const capitalize = (str, lowerRest = false) => Loop through an array of functions containing asynchronous events, calling `next` when each asynchronous event has completed. ```js -const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); } +const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); }; /* chainAsync([ next => { console.log('0 seconds'); setTimeout(next, 1000); }, @@ -159,7 +158,7 @@ If the original array can't be split evenly, the final chunk will contain the re ```js const chunk = (arr, size) => - Array.apply(null, {length: Math.ceil(arr.length/size)}).map((v, i) => arr.slice(i*size, i*size+size)); + Array.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` @@ -207,7 +206,7 @@ Use `Array.reduce()` to get all elements that are not arrays, flatten each eleme ```js const deepFlatten = arr => - arr.reduce( (a, v) => a.concat( Array.isArray(v) ? deepFlatten(v) : v ), []); + arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []); // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] ``` @@ -274,8 +273,8 @@ Create an empty array of the specific length, initializing the first two values Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. ```js -const fibonacci = n => - Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),[]); +const fibonacci = n => + Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []); // fibonacci(5) -> [0,1,1,2,3] ``` @@ -293,7 +292,7 @@ const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexO Use `Array.reduce()` to get all elements inside the array and `concat()` to flatten them. ```js -const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); +const flatten = arr => arr.reduce((a, v) => a.concat(v), []); // flatten([1,[2],3,4]) -> [1,2,3,4] ``` @@ -321,7 +320,7 @@ Returns lower-cased constructor name of value, "undefined" or "null" if value is ```js const getType = v => - v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); + v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); // getType(new Set([1,2,3])) -> "set" ``` @@ -332,8 +331,8 @@ You can omit `el` to use a default value of `window`. ```js const getScrollPos = (el = window) => - ( {x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, - y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop} ); + ({x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, + y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop}); // getScrollPos() -> {x: 0, y: 200} ``` @@ -344,7 +343,7 @@ Base case is when `y` equals `0`. In this case, return `x`. Otherwise, return the GCD of `y` and the remainder of the division `x/y`. ```js -const gcd = (x , y) => !y ? x : gcd(y, x % y); +const gcd = (x, y) => !y ? x : gcd(y, x % y); // gcd (8, 36) -> 4 ``` @@ -355,7 +354,7 @@ Count and return the number of `1`s in the string, using `match(/1/g)`. ```js const hammingDistance = (num1, num2) => - ((num1^num2).toString(2).match(/1/g) || '').length; + ((num1 ^ num2).toString(2).match(/1/g) || '').length; // hammingDistance(2,3) -> 1 ``` @@ -373,7 +372,7 @@ const head = arr => arr[0]; Return `arr.slice(0,-1)`. ```js -const initial = arr => arr.slice(0,-1); +const initial = arr => arr.slice(0, -1); // initial([1,2,3]) -> [1,2] ``` @@ -384,7 +383,7 @@ You can omit `start` to use a default value of `0`. ```js const initializeArrayRange = (end, start = 0) => - Array.apply(null, Array(end-start)).map( (v,i) => i + start ); + Array.apply(null, Array(end - start)).map((v, i) => i + start); // initializeArrayRange(5) -> [0,1,2,3,4] ``` @@ -417,7 +416,7 @@ const timeTaken = callback => { const t0 = performance.now(), r = callback(); console.log(performance.now() - t0); return r; -} +}; // timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) ``` @@ -428,9 +427,9 @@ Return the number at the midpoint if `length` is odd, otherwise the average of t ```js const median = arr => { - const mid = Math.floor(arr.length / 2), nums = arr.sort((a,b) => a - b); + const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; -} +}; // median([5,6,50,1,-5]) -> 5 // median([0,10,-2,7]) -> 3.5 ``` @@ -440,7 +439,7 @@ const median = arr => { Use `Array.reduce()` to create and combine key-value pairs. ```js -const objectFromPairs = arr => arr.reduce((a,v) => (a[v[0]] = v[1], a), {}); +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); // objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} ``` @@ -470,7 +469,7 @@ Use `Array.reduce()` combined with `Array.map()` to iterate over elements and co ```js const powerset = arr => - arr.reduce( (a,v) => a.concat(a.map( r => [v].concat(r) )), [[]]); + arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); // powerset([1,2]) -> [[], [1], [2], [2,1]] ``` @@ -515,7 +514,7 @@ const randomInRange = (min, max) => Math.random() * (max - min) + min; Use `Array.sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. ```js -const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); +const randomizeOrder = arr => arr.sort((a, b) => Math.random() >= 0.5 ? -1 : 1); // randomizeOrder([1,2,3]) -> [1,3,2] ``` @@ -567,11 +566,11 @@ Scroll by a fraction of the distance from top. Use `window.requestAnimationFrame ```js const scrollToTop = _ => { const c = document.documentElement.scrollTop || document.body.scrollTop; - if(c > 0) { + if (c > 0) { window.requestAnimationFrame(scrollToTop); - window.scrollTo(0, c - c/8); + window.scrollTo(0, c - c / 8); } -} +}; // scrollToTop() ``` @@ -583,8 +582,8 @@ Use `Array.sort()` to sort the elements of the original array based on the rando ```js const shuffle = arr => { let r = arr.map(Math.random); - return arr.sort((a,b) => r[a] - r[b]); -} + return arr.sort((a, b) => r[a] - r[b]); +}; // shuffle([1,2,3]) -> [2, 1, 3] ``` @@ -603,7 +602,7 @@ Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, ```js const sortCharactersInString = str => - str.split('').sort( (a,b) => a.localeCompare(b) ).join(''); + str.split('').sort((a, b) => a.localeCompare(b)).join(''); // sortCharactersInString('cabbage') -> 'aabbceg' ``` @@ -612,7 +611,7 @@ const sortCharactersInString = str => Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. ```js -const sum = arr => arr.reduce( (acc , val) => acc + val, 0); +const sum = arr => arr.reduce((acc, val) => acc + val, 0); // sum([1,2,3,4]) -> 10 ``` @@ -642,7 +641,7 @@ Return the string truncated to the desired length, with `...` appended to the en ```js const truncate = (str, num) => - str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; + str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; // truncate('boomerang', 7) -> 'boom...' ``` @@ -663,7 +662,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => url.match(/([^?=&]+)(=([^&]*))?/g).reduce( - (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')+1), a), {} + (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} ``` @@ -674,7 +673,7 @@ Use `crypto` API to generate a UUID, compliant with [RFC4122](https://www.ietf.o ```js const uuid = _ => - ( [1e7]+-1e3+-4e3+-8e3+-1e11 ).replace( /[018]/g, c => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ); // uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' diff --git a/currentSnippet.js b/currentSnippet.js new file mode 100644 index 000000000..544a140b9 --- /dev/null +++ b/currentSnippet.js @@ -0,0 +1,3 @@ + +const valueOrDefault = (value, d) => value || d; +// valueOrDefault(NaN, 30) -> 30 diff --git a/package-lock.json b/package-lock.json index 50c9abf8a..be8bcab8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,40 @@ "negotiator": "0.6.1" } }, + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==" + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=" + }, "ansi-align": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", @@ -26,6 +60,11 @@ "string-width": "2.1.1" } }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" + }, "ansi-regex": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", @@ -79,16 +118,98 @@ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, "array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" }, + "array.prototype.find": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz", + "integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=", + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.10.0" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, "async-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -183,6 +304,24 @@ "repeat-element": "1.1.2" } }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" + }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", @@ -227,11 +366,34 @@ "readdirp": "2.1.0" } }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" + }, "cli-boxes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "requires": { + "restore-cursor": "1.0.1" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -265,6 +427,16 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, "concurrently": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.5.1.tgz", @@ -304,6 +476,11 @@ "utils-merge": "1.0.0" } }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -341,6 +518,14 @@ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "0.10.37" + } + }, "date-fns": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz", @@ -354,11 +539,64 @@ "ms": "0.7.1" } }, + "debug-log": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", + "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=" + }, "deep-extend": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "deglob": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.0.tgz", + "integrity": "sha1-TUSr4W7zLHebSXK9FBqAMlApoUo=", + "requires": { + "find-root": "1.1.0", + "glob": "7.1.2", + "ignore": "3.3.7", + "pkg-config": "1.1.1", + "run-parallel": "1.1.6", + "uniq": "1.0.1" + } + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, "depd": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", @@ -369,6 +607,14 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "doctrine": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", + "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "requires": { + "esutils": "2.0.2" + } + }, "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", @@ -402,11 +648,105 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es-abstract": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, + "es5-ext": { + "version": "0.10.37", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", + "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, "es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=" }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -417,11 +757,288 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "requires": { + "babel-code-frame": "6.26.0", + "chalk": "1.1.3", + "concat-stream": "1.6.0", + "debug": "2.2.0", + "doctrine": "2.0.2", + "escope": "3.6.0", + "espree": "3.5.2", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.7", + "imurmurhash": "0.1.4", + "inquirer": "0.12.0", + "is-my-json-valid": "2.16.1", + "is-resolvable": "1.0.1", + "js-yaml": "3.10.0", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "1.2.1", + "progress": "1.1.8", + "require-uncached": "1.0.3", + "shelljs": "0.7.8", + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1", + "table": "3.8.3", + "text-table": "0.2.0", + "user-home": "2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "eslint-config-semistandard": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-semistandard/-/eslint-config-semistandard-11.0.0.tgz", + "integrity": "sha1-RO73z9/Uchnjp7gbkbVA6IC7JhU=" + }, + "eslint-config-standard": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", + "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=" + }, + "eslint-config-standard-jsx": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.1.tgz", + "integrity": "sha1-zU5GPQJo4tnnB/YfQvc/WzMzxkI=" + }, + "eslint-import-resolver-node": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz", + "integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=", + "requires": { + "debug": "2.2.0", + "object-assign": "4.1.1", + "resolve": "1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", + "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", + "requires": { + "debug": "2.6.9", + "pkg-dir": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "eslint-plugin-import": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz", + "integrity": "sha1-crowb60wXWfEgWNIpGmaQimsi04=", + "requires": { + "builtin-modules": "1.1.1", + "contains-path": "0.1.0", + "debug": "2.2.0", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "0.2.3", + "eslint-module-utils": "2.1.1", + "has": "1.0.1", + "lodash.cond": "4.5.2", + "minimatch": "3.0.4", + "pkg-up": "1.0.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + } + } + }, + "eslint-plugin-node": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz", + "integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==", + "requires": { + "ignore": "3.3.7", + "minimatch": "3.0.4", + "object-assign": "4.1.1", + "resolve": "1.5.0", + "semver": "5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + } + } + }, + "eslint-plugin-promise": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", + "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=" + }, + "eslint-plugin-react": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz", + "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=", + "requires": { + "array.prototype.find": "2.0.4", + "doctrine": "1.5.0", + "has": "1.0.1", + "jsx-ast-utils": "1.4.1", + "object.assign": "4.0.4" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + } + } + }, + "eslint-plugin-standard": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", + "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=" + }, + "espree": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", + "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "requires": { + "acorn": "5.2.1", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37" + } + }, "event-stream": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", @@ -450,6 +1067,11 @@ "strip-eof": "1.0.0" } }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=" + }, "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", @@ -474,6 +1096,11 @@ "is-extglob": "1.0.0" } }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, "faye-websocket": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", @@ -482,6 +1109,24 @@ "websocket-driver": "0.7.0" } }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -511,6 +1156,31 @@ "unpipe": "1.0.0" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -524,6 +1194,11 @@ "for-in": "1.0.2" } }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -544,11 +1219,52 @@ "universalify": "0.1.1" } }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=" + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "requires": { + "is-property": "1.0.2" + } + }, + "get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=" + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, "glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", @@ -574,6 +1290,31 @@ "ini": "1.3.5" } }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, "got": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", @@ -597,6 +1338,14 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "requires": { + "function-bind": "1.1.1" + } + }, "has-ansi": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", @@ -637,6 +1386,11 @@ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz", "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE=" }, + "ignore": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==" + }, "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", @@ -652,6 +1406,15 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -662,6 +1425,99 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "requires": { + "ansi-escapes": "1.4.0", + "ansi-regex": "2.1.1", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.2.0", + "figures": "1.7.0", + "lodash": "4.17.4", + "readline2": "1.0.1", + "run-async": "0.1.0", + "rx-lite": "3.1.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -675,6 +1531,16 @@ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -720,6 +1586,17 @@ "is-path-inside": "1.0.1" } }, + "is-my-json-valid": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", + "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, "is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", @@ -738,6 +1615,19 @@ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "requires": { + "is-path-inside": "1.0.1" + } + }, "is-path-inside": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", @@ -756,11 +1646,29 @@ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, "is-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "1.0.1" + } + }, + "is-resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", + "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==" + }, "is-retry-allowed": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", @@ -771,6 +1679,11 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" + }, "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", @@ -794,6 +1707,28 @@ "isarray": "1.0.0" } }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "0.0.0" + } + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -802,6 +1737,21 @@ "graceful-fs": "4.1.11" } }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=" + }, + "jsx-ast-utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", + "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=" + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -818,6 +1768,15 @@ "package-json": "4.0.1" } }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, "linkify-it": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz", @@ -846,6 +1805,40 @@ "serve-index": "1.9.1" } }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + } + } + }, "lodash": { "version": "4.17.4", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", @@ -900,6 +1893,11 @@ "lodash.keys": "3.1.2" } }, + "lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=" + }, "lodash.defaults": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-3.1.2.tgz", @@ -1029,6 +2027,21 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, "morgan": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz", @@ -1061,6 +2074,16 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -1132,6 +2155,21 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=" + }, + "object.assign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz", + "integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw=", + "requires": { + "define-properties": "1.1.2", + "function-bind": "1.1.1", + "object-keys": "1.0.11" + } + }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", @@ -1154,6 +2192,19 @@ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" + }, "opn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz", @@ -1162,11 +2213,42 @@ "is-wsl": "1.1.0" } }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=" + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "1.1.0" + } + }, "package-json": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", @@ -1189,11 +2271,27 @@ "is-glob": "2.0.1" } }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "1.3.1" + } + }, "parseurl": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "2.0.1" + } + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1209,6 +2307,11 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" + }, "pause-stream": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", @@ -1222,6 +2325,74 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-conf": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.0.0.tgz", + "integrity": "sha1-BxyHZQQDvM+5xif1h1G/5HwGcnk=", + "requires": { + "find-up": "2.1.0", + "load-json-file": "2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "2.0.0" + } + } + } + }, + "pkg-config": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", + "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", + "requires": { + "debug-log": "1.0.1", + "find-root": "1.1.0", + "xtend": "4.0.1" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "requires": { + "find-up": "1.1.2" + } + }, + "pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", + "requires": { + "find-up": "1.1.2" + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", @@ -1237,6 +2408,11 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" + }, "proxy-middleware": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", @@ -1333,6 +2509,34 @@ "set-immediate-shim": "1.0.1" } }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "mute-stream": "0.0.5" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + } + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "1.5.0" + } + }, "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", @@ -1373,16 +2577,90 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "7.1.2" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "requires": { + "once": "1.4.0" + } + }, + "run-parallel": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.6.tgz", + "integrity": "sha1-KQA8miFj4B4tLfyQV18sbB1hoDk=" + }, "rx": { "version": "2.3.24", "resolved": "https://registry.npmjs.org/rx/-/rx-2.3.24.tgz", "integrity": "sha1-FPlQpCF9fjXapxu8vljv9o6ksrc=" }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=" + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, + "semistandard": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/semistandard/-/semistandard-11.0.0.tgz", + "integrity": "sha1-0tn8isOT3iExIZXgBuUMiGE5HEc=", + "requires": { + "eslint": "3.19.0", + "eslint-config-semistandard": "11.0.0", + "eslint-config-standard": "10.2.1", + "eslint-config-standard-jsx": "4.0.1", + "eslint-plugin-import": "2.2.0", + "eslint-plugin-node": "4.2.3", + "eslint-plugin-promise": "3.5.0", + "eslint-plugin-react": "6.10.3", + "eslint-plugin-standard": "3.0.1", + "standard-engine": "7.0.0" + } + }, "semver": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", @@ -1483,11 +2761,26 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "requires": { + "glob": "7.1.2", + "interpret": "1.1.0", + "rechoir": "0.6.2" + } + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=" + }, "spawn-command": { "version": "0.0.2-1", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", @@ -1506,6 +2799,17 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "standard-engine": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz", + "integrity": "sha1-67d7nI/CyBZf+jU72Rug3/Qa9pA=", + "requires": { + "deglob": "2.1.0", + "get-stdin": "5.0.1", + "minimist": "1.2.0", + "pkg-conf": "2.0.0" + } + }, "statuses": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", @@ -1559,6 +2863,11 @@ "ansi-regex": "0.2.1" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -1577,6 +2886,64 @@ "has-flag": "1.0.0" } }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "requires": { + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.4", + "slice-ansi": "0.0.4", + "string-width": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, "term-size": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", @@ -1585,6 +2952,11 @@ "execa": "0.7.0" } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -1608,6 +2980,19 @@ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==" }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "uc.micro": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.3.tgz", @@ -1618,6 +3003,11 @@ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-0.0.3.tgz", "integrity": "sha1-7Mo6A+VrmvFzhbqsgSrIO5lKli8=" }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, "unique-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", @@ -1703,6 +3093,14 @@ "prepend-http": "1.0.4" } }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "requires": { + "os-homedir": "1.0.2" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -1786,6 +3184,24 @@ } } }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "requires": { + "mkdirp": "0.5.1" + } + }, "write-file-atomic": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", @@ -1801,6 +3217,11 @@ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", diff --git a/package.json b/package.json index d4e46f083..a616c02d0 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "fs-extra": "^4.0.2", "live-server": "^1.2.0", "markdown-it": "^8.4.0", - "nodemon": "^1.12.1" + "nodemon": "^1.12.1", + "semistandard": "^11.0.0" }, "name": "30-seconds-of-code", "description": "A collection of useful Javascript snippets.", @@ -13,6 +14,7 @@ "devDependencies": {}, "scripts": { "build-list": "node ./scripts/builder.js", + "lint": "node ./scripts/lintSnippet.js", "start": "concurrently --kill-others \"nodemon -e js,md -i README.md -x \\\"npm run build-list\\\"\" \"live-server ./build\"" }, "repository": { diff --git a/scripts/builder.js b/scripts/builder.js index b3305147a..b9a5d5bc8 100644 --- a/scripts/builder.js +++ b/scripts/builder.js @@ -6,6 +6,8 @@ var staticPartsPath = './static-parts'; var snippets = {}, startPart = '', endPart = '', output = ''; +console.time('Builder'); + try { var snippetFilenames = fs.readdirSync(snippetsPath); snippetFilenames.sort((a, b) => { @@ -51,3 +53,5 @@ catch (err){ console.log('Error during README generation: '+err); process.exit(1); } + +console.timeEnd('Builder'); diff --git a/scripts/lintSnippet.js b/scripts/lintSnippet.js new file mode 100644 index 000000000..a53686ee5 --- /dev/null +++ b/scripts/lintSnippet.js @@ -0,0 +1,31 @@ +var fs = require('fs-extra'); +var cp = require('child_process'); +var path = require('path'); + +var snippetsPath = './snippets'; +var snippetFilename = ''; + +console.time('Linter'); + +if(process.argv.length < 3){ + console.log('Please specify the filename of a snippet to be linted.'); + console.log('Example usage: npm run lint "snippet-file.md"'); + process.exit(0); +} +else { + snippetFilename = process.argv[2]; + let snippetData = fs.readFileSync(path.join(snippetsPath,snippetFilename),'utf8'); + try { + let originalCode = snippetData.slice(snippetData.indexOf('```js')+5,snippetData.lastIndexOf('```')); + fs.writeFileSync('currentSnippet.js',`${originalCode}`); + cp.exec('semistandard "currentSnippet.js" --fix',{},(error, stdOut, stdErr) => { + let lintedCode = fs.readFileSync('currentSnippet.js','utf8'); + fs.writeFile(path.join(snippetsPath,snippetFilename), `${snippetData.slice(0, snippetData.indexOf('```js')+5)+lintedCode+'```\n'}`); + console.timeEnd('Linter'); + }); + } + catch (err){ + console.log('Error during snippet loading: '+err); + process.exit(1); + } +} diff --git a/semi-snippets.js b/semi-snippets.js new file mode 100644 index 000000000..c35e9d6b8 --- /dev/null +++ b/semi-snippets.js @@ -0,0 +1,242 @@ + +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)), []); +}; +// anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] + +const average = arr => + arr.reduce((acc, val) => acc + val, 0) / arr.length; +// average([1,2,3]) -> 2 + +const bottomVisible = _ => + document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; +// bottomVisible() -> true + +const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); +// capitalizeEveryWord('hello world!') -> 'Hello World!' + +const capitalize = (str, lowerRest = false) => + str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); +// capitalize('myName', true) -> 'Myname' + +const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); }; +/* +chainAsync([ + next => { console.log('0 seconds'); setTimeout(next, 1000); }, + next => { console.log('1 second'); setTimeout(next, 1000); }, + next => { console.log('2 seconds'); } +]) +*/ + +const palindrome = str => + str.toLowerCase().replace(/[\W_]/g, '').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g, ''); +// palindrome('taco cat') -> true + +const chunk = (arr, size) => + Array.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); +// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] + +const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); +// countOccurrences([1,1,2,1,2,3], 1) -> 3 + +const currentUrl = _ => window.location.href; +// currentUrl() -> 'https://google.com' + +const curry = (f, arity = f.length, next) => + (next = prevArgs => + nextArg => { + const args = [ ...prevArgs, nextArg ]; + return args.length >= arity ? f(...args) : next(args); + } + )([]); +// curry(Math.pow)(2)(10) -> 1024 +// curry(Math.min, 3)(10)(50)(2) -> 2 + +const deepFlatten = arr => + arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []); +// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] + +const difference = (arr, values) => arr.filter(v => !values.includes(v)); +// difference([1,2,3], [1,2]) -> [3] + +const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); +// distance(1,1, 2,3) -> 2.23606797749979 + +const isDivisible = (dividend, divisor) => dividend % divisor === 0; +// isDivisible(6,3) -> true + +const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +// escapeRegExp('(test)') -> \\(test\\) + +const isEven = num => Math.abs(num) % 2 === 0; +// isEven(3) -> false + +const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); +// factorial(6) -> 720 + +const fibonacci = n => + Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []); +// fibonacci(5) -> [0,1,1,2,3] + +const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); +// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] + +const flatten = arr => arr.reduce((a, v) => a.concat(v), []); +// flatten([1,[2],3,4]) -> [1,2,3,4] + +const arrayMax = arr => Math.max(...arr); +// arrayMax([10, 1, 5]) -> 10 + +const arrayMin = arr => Math.min(...arr); +// arrayMin([10, 1, 5]) -> 1 + +const getType = v => + v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); +// getType(new Set([1,2,3])) -> "set" + +const getScrollPos = (el = window) => + ({x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, + y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop}); +// getScrollPos() -> {x: 0, y: 200} + +const gcd = (x, y) => !y ? x : gcd(y, x % y); +// gcd (8, 36) -> 4 + +const hammingDistance = (num1, num2) => + ((num1 ^ num2).toString(2).match(/1/g) || '').length; +// hammingDistance(2,3) -> 1 + +const head = arr => arr[0]; +// head([1,2,3]) -> 1 + +const initial = arr => arr.slice(0, -1); +// initial([1,2,3]) -> [1,2] + +const initializeArrayRange = (end, start = 0) => + Array.apply(null, Array(end - start)).map((v, i) => i + start); +// initializeArrayRange(5) -> [0,1,2,3,4] + +const initializeArray = (n, value = 0) => Array(n).fill(value); +// initializeArray(5, 2) -> [2,2,2,2,2] + +const last = arr => arr.slice(-1)[0]; +// last([1,2,3]) -> 3 + +const timeTaken = callback => { + const t0 = performance.now(), r = callback(); + console.log(performance.now() - t0); + return r; +}; +// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) + +const median = arr => { + const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +}; +// median([5,6,50,1,-5]) -> 5 +// median([0,10,-2,7]) -> 3.5 + +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); +// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} + +const percentile = (arr, val) => + 100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; +// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 + +const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg); +// pipe(btoa, x => x.toUpperCase())("Test") -> "VGVZDA==" + +const powerset = arr => + arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); +// powerset([1,2]) -> [[], [1], [2], [2,1]] + +const promisify = func => + (...args) => + new Promise((resolve, reject) => + func(...args, (err, result) => + err ? reject(err) : resolve(result)) + ); +// const delay = promisify((d, cb) => setTimeout(cb, d)) +// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s + +const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; +// randomIntegerInRange(0, 5) -> 2 + +const randomInRange = (min, max) => Math.random() * (max - min) + min; +// randomInRange(2,10) -> 6.0211363285087005 + +const randomizeOrder = arr => arr.sort((a, b) => Math.random() >= 0.5 ? -1 : 1); +// randomizeOrder([1,2,3]) -> [1,3,2] + +const redirect = (url, asLink = true) => + asLink ? window.location.href = url : window.location.replace(url); +// redirect('https://google.com') + +const reverseString = str => [...str].reverse().join(''); +// reverseString('foobar') -> 'raboof' + +const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); +// rgbToHex(255, 165, 1) -> 'ffa501' + +const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); +// const delay = (d) => new Promise(r => setTimeout(r, d)) +// series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete + +const scrollToTop = _ => { + const c = document.documentElement.scrollTop || document.body.scrollTop; + if (c > 0) { + window.requestAnimationFrame(scrollToTop); + window.scrollTo(0, c - c / 8); + } +}; +// scrollToTop() + +const shuffle = arr => { + let r = arr.map(Math.random); + return arr.sort((a, b) => r[a] - r[b]); +}; +// shuffle([1,2,3]) -> [2, 1, 3] + +const similarity = (arr, values) => arr.filter(v => values.includes(v)); +// similarity([1,2,3], [1,2,4]) -> [1,2] + +const sortCharactersInString = str => + str.split('').sort((a, b) => a.localeCompare(b)).join(''); +// sortCharactersInString('cabbage') -> 'aabbceg' + +const sum = arr => arr.reduce((acc, val) => acc + val, 0); +// sum([1,2,3,4]) -> 10 + +[varA, varB] = [varB, varA]; +// [x, y] = [y, x] + +const tail = arr => arr.length > 1 ? arr.slice(1) : arr; +// tail([1,2,3]) -> [2,3] +// tail([1]) -> [1] + +const truncate = (str, num) => + str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; +// truncate('boomerang', 7) -> 'boom...' + +const unique = arr => [...new Set(arr)]; +// unique([1,2,2,3,4,4,5]) -> [1,2,3,4,5] + +const getUrlParameters = url => + url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} + ); +// getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} + +const uuid = _ => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) + ); +// uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' + +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); +// validateNumber('10') -> true + +const valueOrDefault = (value, d) => value || d; +// valueOrDefault(NaN, 30) -> 30 diff --git a/snippets.js b/snippets.js new file mode 100644 index 000000000..d754bf389 --- /dev/null +++ b/snippets.js @@ -0,0 +1,302 @@ + +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 )), []); +} +// anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] + + +const average = arr => + arr.reduce( (acc , val) => acc + val, 0) / arr.length; +// average([1,2,3]) -> 2 + + +const bottomVisible = _ => + document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; +// bottomVisible() -> true + + +const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); +// capitalizeEveryWord('hello world!') -> 'Hello World!' + + +const capitalize = (str, lowerRest = false) => + str.slice(0, 1).toUpperCase() + (lowerRest? str.slice(1).toLowerCase() : str.slice(1)); +// capitalize('myName', true) -> 'Myname' + + +const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); } +/* +chainAsync([ + next => { console.log('0 seconds'); setTimeout(next, 1000); }, + next => { console.log('1 second'); setTimeout(next, 1000); }, + next => { console.log('2 seconds'); } +]) +*/ + + +const palindrome = str => + str.toLowerCase().replace(/[\W_]/g,'').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g,''); +// palindrome('taco cat') -> true + + +const chunk = (arr, size) => + Array.apply(null, {length: Math.ceil(arr.length/size)}).map((v, i) => arr.slice(i*size, i*size+size)); +// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] + + +const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); +// countOccurrences([1,1,2,1,2,3], 1) -> 3 + + +const currentUrl = _ => window.location.href; +// currentUrl() -> 'https://google.com' + + +const curry = (f, arity = f.length, next) => + (next = prevArgs => + nextArg => { + const args = [ ...prevArgs, nextArg ]; + return args.length >= arity ? f(...args) : next(args); + } + )([]); +// curry(Math.pow)(2)(10) -> 1024 +// curry(Math.min, 3)(10)(50)(2) -> 2 + + +const deepFlatten = arr => + arr.reduce( (a, v) => a.concat( Array.isArray(v) ? deepFlatten(v) : v ), []); +// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] + + +const difference = (arr, values) => arr.filter(v => !values.includes(v)); +// difference([1,2,3], [1,2]) -> [3] + + +const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); +// distance(1,1, 2,3) -> 2.23606797749979 + + +const isDivisible = (dividend, divisor) => dividend % divisor === 0; +// isDivisible(6,3) -> true + + +const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +// escapeRegExp('(test)') -> \\(test\\) + + +const isEven = num => Math.abs(num) % 2 === 0; +// isEven(3) -> false + + +const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); +// factorial(6) -> 720 + + +const fibonacci = n => + Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),[]); +// fibonacci(5) -> [0,1,1,2,3] + + +const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); +// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] + + +const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); +// flatten([1,[2],3,4]) -> [1,2,3,4] + + +const arrayMax = arr => Math.max(...arr); +// arrayMax([10, 1, 5]) -> 10 + + +const arrayMin = arr => Math.min(...arr); +// arrayMin([10, 1, 5]) -> 1 + + +const getType = v => + v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); +// getType(new Set([1,2,3])) -> "set" + + +const getScrollPos = (el = window) => + ( {x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, + y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop} ); +// getScrollPos() -> {x: 0, y: 200} + + +const gcd = (x , y) => !y ? x : gcd(y, x % y); +// gcd (8, 36) -> 4 + + +const hammingDistance = (num1, num2) => + ((num1^num2).toString(2).match(/1/g) || '').length; +// hammingDistance(2,3) -> 1 + + +const head = arr => arr[0]; +// head([1,2,3]) -> 1 + + +const initial = arr => arr.slice(0,-1); +// initial([1,2,3]) -> [1,2] + + +const initializeArrayRange = (end, start = 0) => + Array.apply(null, Array(end-start)).map( (v,i) => i + start ); +// initializeArrayRange(5) -> [0,1,2,3,4] + + +const initializeArray = (n, value = 0) => Array(n).fill(value); +// initializeArray(5, 2) -> [2,2,2,2,2] + + +const last = arr => arr.slice(-1)[0]; +// last([1,2,3]) -> 3 + + +const timeTaken = callback => { + const t0 = performance.now(), r = callback(); + console.log(performance.now() - t0); + return r; +} +// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) + + +const median = arr => { + const mid = Math.floor(arr.length / 2), nums = arr.sort((a,b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +} +// median([5,6,50,1,-5]) -> 5 +// median([0,10,-2,7]) -> 3.5 + + +const objectFromPairs = arr => arr.reduce((a,v) => (a[v[0]] = v[1], a), {}); +// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} + + +const percentile = (arr, val) => + 100 * arr.reduce((acc,v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; +// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 + + +const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg); +// pipe(btoa, x => x.toUpperCase())("Test") -> "VGVZDA==" + + +const powerset = arr => + arr.reduce( (a,v) => a.concat(a.map( r => [v].concat(r) )), [[]]); +// powerset([1,2]) -> [[], [1], [2], [2,1]] + + +const promisify = func => + (...args) => + new Promise((resolve, reject) => + func(...args, (err, result) => + err ? reject(err) : resolve(result)) + ); +// const delay = promisify((d, cb) => setTimeout(cb, d)) +// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s + + +const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; +// randomIntegerInRange(0, 5) -> 2 + + +const randomInRange = (min, max) => Math.random() * (max - min) + min; +// randomInRange(2,10) -> 6.0211363285087005 + + +const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); +// randomizeOrder([1,2,3]) -> [1,3,2] + + +const redirect = (url, asLink = true) => + asLink ? window.location.href = url : window.location.replace(url); +// redirect('https://google.com') + + +const reverseString = str => [...str].reverse().join(''); +// reverseString('foobar') -> 'raboof' + + +const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); +// rgbToHex(255, 165, 1) -> 'ffa501' + + +const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); +// const delay = (d) => new Promise(r => setTimeout(r, d)) +// series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete + + +const scrollToTop = _ => { + const c = document.documentElement.scrollTop || document.body.scrollTop; + if(c > 0) { + window.requestAnimationFrame(scrollToTop); + window.scrollTo(0, c - c/8); + } +} +// scrollToTop() + + +const shuffle = arr => { + let r = arr.map(Math.random); + return arr.sort((a,b) => r[a] - r[b]); +} +// shuffle([1,2,3]) -> [2, 1, 3] + + +const similarity = (arr, values) => arr.filter(v => values.includes(v)); +// similarity([1,2,3], [1,2,4]) -> [1,2] + + +const sortCharactersInString = str => + str.split('').sort( (a,b) => a.localeCompare(b) ).join(''); +// sortCharactersInString('cabbage') -> 'aabbceg' + + +const sum = arr => arr.reduce( (acc , val) => acc + val, 0); +// sum([1,2,3,4]) -> 10 + + +[varA, varB] = [varB, varA]; +// [x, y] = [y, x] + + +const tail = arr => arr.length > 1 ? arr.slice(1) : arr; +// tail([1,2,3]) -> [2,3] +// tail([1]) -> [1] + + +const truncate = (str, num) => + str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; +// truncate('boomerang', 7) -> 'boom...' + + +const unique = arr => [...new Set(arr)]; +// unique([1,2,2,3,4,4,5]) -> [1,2,3,4,5] + + +const getUrlParameters = url => + url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')+1), a), {} + ); +// getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} + + +const uuid = _ => + ( [1e7]+-1e3+-4e3+-8e3+-1e11 ).replace( /[018]/g, c => + (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) + ); +// uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' + + +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); +// validateNumber('10') -> true + + +const valueOrDefault = (value, d) => value || d; +// valueOrDefault(NaN, 30) -> 30 + + diff --git a/snippets/URL-parameters.md b/snippets/URL-parameters.md index c5a316b76..742e7ffbd 100644 --- a/snippets/URL-parameters.md +++ b/snippets/URL-parameters.md @@ -6,7 +6,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => url.match(/([^?=&]+)(=([^&]*))?/g).reduce( - (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')+1), a), {} + (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} ``` diff --git a/snippets/UUID-generator.md b/snippets/UUID-generator.md index b7860cf64..01d4e27ac 100644 --- a/snippets/UUID-generator.md +++ b/snippets/UUID-generator.md @@ -4,7 +4,7 @@ Use `crypto` API to generate a UUID, compliant with [RFC4122](https://www.ietf.o ```js const uuid = _ => - ( [1e7]+-1e3+-4e3+-8e3+-1e11 ).replace( /[018]/g, c => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ); // uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' diff --git a/snippets/anagrams-of-string-(with-duplicates).md b/snippets/anagrams-of-string-(with-duplicates).md index 7e1d613b6..bbc2e3dfb 100644 --- a/snippets/anagrams-of-string-(with-duplicates).md +++ b/snippets/anagrams-of-string-(with-duplicates).md @@ -7,9 +7,9 @@ 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 )), []); -} + 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)), []); +}; // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` diff --git a/snippets/average-of-array-of-numbers.md b/snippets/average-of-array-of-numbers.md index 8d9aaf1cd..73ae7bc39 100644 --- a/snippets/average-of-array-of-numbers.md +++ b/snippets/average-of-array-of-numbers.md @@ -3,7 +3,6 @@ Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. ```js -const average = arr => - arr.reduce( (acc , val) => acc + val, 0) / arr.length; +const average = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length; // average([1,2,3]) -> 2 ``` diff --git a/snippets/bottom-visible.md b/snippets/bottom-visible.md index 9045c6bff..b94ac773a 100644 --- a/snippets/bottom-visible.md +++ b/snippets/bottom-visible.md @@ -3,7 +3,7 @@ Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible. ```js -const bottomVisible = _ => +const bottomVisible = _ => document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; // bottomVisible() -> true ``` diff --git a/snippets/capitalize-first-letter.md b/snippets/capitalize-first-letter.md index 99be77927..61f73b6a7 100644 --- a/snippets/capitalize-first-letter.md +++ b/snippets/capitalize-first-letter.md @@ -5,6 +5,6 @@ Omit the `lowerRest` parameter to keep the rest of the string intact, or set it ```js const capitalize = (str, lowerRest = false) => - str.slice(0, 1).toUpperCase() + (lowerRest? str.slice(1).toLowerCase() : str.slice(1)); + str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); // capitalize('myName', true) -> 'Myname' ``` diff --git a/snippets/chain-asynchronous-functions.md b/snippets/chain-asynchronous-functions.md index 6c6118b3c..8aec5d186 100644 --- a/snippets/chain-asynchronous-functions.md +++ b/snippets/chain-asynchronous-functions.md @@ -3,7 +3,7 @@ Loop through an array of functions containing asynchronous events, calling `next` when each asynchronous event has completed. ```js -const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); } +const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); }; /* chainAsync([ next => { console.log('0 seconds'); setTimeout(next, 1000); }, diff --git a/snippets/chunk-array.md b/snippets/chunk-array.md index 8f92499a2..de6c5a568 100644 --- a/snippets/chunk-array.md +++ b/snippets/chunk-array.md @@ -6,6 +6,6 @@ If the original array can't be split evenly, the final chunk will contain the re ```js const chunk = (arr, size) => - Array.apply(null, {length: Math.ceil(arr.length/size)}).map((v, i) => arr.slice(i*size, i*size+size)); + Array.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` diff --git a/snippets/deep-flatten-array.md b/snippets/deep-flatten-array.md index 397d62241..c350d848c 100644 --- a/snippets/deep-flatten-array.md +++ b/snippets/deep-flatten-array.md @@ -5,6 +5,6 @@ Use `Array.reduce()` to get all elements that are not arrays, flatten each eleme ```js const deepFlatten = arr => - arr.reduce( (a, v) => a.concat( Array.isArray(v) ? deepFlatten(v) : v ), []); + arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []); // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] ``` diff --git a/snippets/fibonacci-array-generator.md b/snippets/fibonacci-array-generator.md index 0255e8875..7f0d4c7d2 100644 --- a/snippets/fibonacci-array-generator.md +++ b/snippets/fibonacci-array-generator.md @@ -4,7 +4,7 @@ Create an empty array of the specific length, initializing the first two values Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. ```js -const fibonacci = n => - Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),[]); +const fibonacci = n => + Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []); // fibonacci(5) -> [0,1,1,2,3] ``` diff --git a/snippets/flatten-array.md b/snippets/flatten-array.md index 224060d02..d23f24611 100644 --- a/snippets/flatten-array.md +++ b/snippets/flatten-array.md @@ -3,6 +3,6 @@ Use `Array.reduce()` to get all elements inside the array and `concat()` to flatten them. ```js -const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); +const flatten = arr => arr.reduce((a, v) => a.concat(v), []); // flatten([1,[2],3,4]) -> [1,2,3,4] ``` diff --git a/snippets/get-native-type-of-value.md b/snippets/get-native-type-of-value.md index d2ded3f83..9e043a83e 100644 --- a/snippets/get-native-type-of-value.md +++ b/snippets/get-native-type-of-value.md @@ -4,6 +4,6 @@ Returns lower-cased constructor name of value, "undefined" or "null" if value is ```js const getType = v => - v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); + v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); // getType(new Set([1,2,3])) -> "set" ``` diff --git a/snippets/get-scroll-position.md b/snippets/get-scroll-position.md index 7e367168f..4f134a9fb 100644 --- a/snippets/get-scroll-position.md +++ b/snippets/get-scroll-position.md @@ -5,7 +5,7 @@ You can omit `el` to use a default value of `window`. ```js const getScrollPos = (el = window) => - ( {x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, - y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop} ); + ({x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, + y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop}); // getScrollPos() -> {x: 0, y: 200} ``` diff --git a/snippets/greatest-common-divisor-(GCD).md b/snippets/greatest-common-divisor-(GCD).md index 38b5603ca..d1025a029 100644 --- a/snippets/greatest-common-divisor-(GCD).md +++ b/snippets/greatest-common-divisor-(GCD).md @@ -5,6 +5,6 @@ Base case is when `y` equals `0`. In this case, return `x`. Otherwise, return the GCD of `y` and the remainder of the division `x/y`. ```js -const gcd = (x , y) => !y ? x : gcd(y, x % y); +const gcd = (x, y) => !y ? x : gcd(y, x % y); // gcd (8, 36) -> 4 ``` diff --git a/snippets/hamming-distance.md b/snippets/hamming-distance.md index 5b47db022..e524408a8 100644 --- a/snippets/hamming-distance.md +++ b/snippets/hamming-distance.md @@ -5,6 +5,6 @@ Count and return the number of `1`s in the string, using `match(/1/g)`. ```js const hammingDistance = (num1, num2) => - ((num1^num2).toString(2).match(/1/g) || '').length; + ((num1 ^ num2).toString(2).match(/1/g) || '').length; // hammingDistance(2,3) -> 1 ``` diff --git a/snippets/initial-of-list.md b/snippets/initial-of-list.md index 77ea3e8f7..a222f2306 100644 --- a/snippets/initial-of-list.md +++ b/snippets/initial-of-list.md @@ -3,6 +3,6 @@ Return `arr.slice(0,-1)`. ```js -const initial = arr => arr.slice(0,-1); +const initial = arr => arr.slice(0, -1); // initial([1,2,3]) -> [1,2] ``` diff --git a/snippets/initialize-array-with-range.md b/snippets/initialize-array-with-range.md index 03de99eb2..def23fb9c 100644 --- a/snippets/initialize-array-with-range.md +++ b/snippets/initialize-array-with-range.md @@ -5,6 +5,6 @@ You can omit `start` to use a default value of `0`. ```js const initializeArrayRange = (end, start = 0) => - Array.apply(null, Array(end-start)).map( (v,i) => i + start ); + Array.apply(null, Array(end - start)).map((v, i) => i + start); // initializeArrayRange(5) -> [0,1,2,3,4] ``` diff --git a/snippets/measure-time-taken-by-function.md b/snippets/measure-time-taken-by-function.md index 73d32141e..44e099d7e 100644 --- a/snippets/measure-time-taken-by-function.md +++ b/snippets/measure-time-taken-by-function.md @@ -8,6 +8,6 @@ const timeTaken = callback => { const t0 = performance.now(), r = callback(); console.log(performance.now() - t0); return r; -} +}; // timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) ``` diff --git a/snippets/median-of-array-of-numbers.md b/snippets/median-of-array-of-numbers.md index 3a675a545..8113d51c6 100644 --- a/snippets/median-of-array-of-numbers.md +++ b/snippets/median-of-array-of-numbers.md @@ -5,9 +5,9 @@ Return the number at the midpoint if `length` is odd, otherwise the average of t ```js const median = arr => { - const mid = Math.floor(arr.length / 2), nums = arr.sort((a,b) => a - b); + const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; -} +}; // median([5,6,50,1,-5]) -> 5 // median([0,10,-2,7]) -> 3.5 ``` diff --git a/snippets/object-from-key-value-pairs.md b/snippets/object-from-key-value-pairs.md index df01da0ba..cbb545c06 100644 --- a/snippets/object-from-key-value-pairs.md +++ b/snippets/object-from-key-value-pairs.md @@ -3,6 +3,6 @@ Use `Array.reduce()` to create and combine key-value pairs. ```js -const objectFromPairs = arr => arr.reduce((a,v) => (a[v[0]] = v[1], a), {}); +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); // objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} ``` diff --git a/snippets/powerset.md b/snippets/powerset.md index 62ec96655..73b71b645 100644 --- a/snippets/powerset.md +++ b/snippets/powerset.md @@ -4,6 +4,6 @@ Use `Array.reduce()` combined with `Array.map()` to iterate over elements and co ```js const powerset = arr => - arr.reduce( (a,v) => a.concat(a.map( r => [v].concat(r) )), [[]]); + arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); // powerset([1,2]) -> [[], [1], [2], [2,1]] ``` diff --git a/snippets/randomize-order-of-array.md b/snippets/randomize-order-of-array.md index d65aaf444..456a00607 100644 --- a/snippets/randomize-order-of-array.md +++ b/snippets/randomize-order-of-array.md @@ -3,6 +3,6 @@ Use `Array.sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. ```js -const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); +const randomizeOrder = arr => arr.sort((a, b) => Math.random() >= 0.5 ? -1 : 1); // randomizeOrder([1,2,3]) -> [1,3,2] ``` diff --git a/snippets/scroll-to-top.md b/snippets/scroll-to-top.md index 7a813429a..6c82190a4 100644 --- a/snippets/scroll-to-top.md +++ b/snippets/scroll-to-top.md @@ -6,10 +6,10 @@ Scroll by a fraction of the distance from top. Use `window.requestAnimationFrame ```js const scrollToTop = _ => { const c = document.documentElement.scrollTop || document.body.scrollTop; - if(c > 0) { + if (c > 0) { window.requestAnimationFrame(scrollToTop); - window.scrollTo(0, c - c/8); + window.scrollTo(0, c - c / 8); } -} +}; // scrollToTop() ``` diff --git a/snippets/shuffle-array-values.md b/snippets/shuffle-array-values.md index a140bd647..ab3698a31 100644 --- a/snippets/shuffle-array-values.md +++ b/snippets/shuffle-array-values.md @@ -6,7 +6,7 @@ Use `Array.sort()` to sort the elements of the original array based on the rando ```js const shuffle = arr => { let r = arr.map(Math.random); - return arr.sort((a,b) => r[a] - r[b]); -} + return arr.sort((a, b) => r[a] - r[b]); +}; // shuffle([1,2,3]) -> [2, 1, 3] ``` diff --git a/snippets/sort-characters-in-string-(alphabetical).md b/snippets/sort-characters-in-string-(alphabetical).md index 7ed73cb14..9cf37ad77 100644 --- a/snippets/sort-characters-in-string-(alphabetical).md +++ b/snippets/sort-characters-in-string-(alphabetical).md @@ -4,6 +4,6 @@ Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, ```js const sortCharactersInString = str => - str.split('').sort( (a,b) => a.localeCompare(b) ).join(''); + str.split('').sort((a, b) => a.localeCompare(b)).join(''); // sortCharactersInString('cabbage') -> 'aabbceg' ``` diff --git a/snippets/sum-of-array-of-numbers.md b/snippets/sum-of-array-of-numbers.md index 939106cc1..9729eb474 100644 --- a/snippets/sum-of-array-of-numbers.md +++ b/snippets/sum-of-array-of-numbers.md @@ -3,6 +3,6 @@ Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. ```js -const sum = arr => arr.reduce( (acc , val) => acc + val, 0); +const sum = arr => arr.reduce((acc, val) => acc + val, 0); // sum([1,2,3,4]) -> 10 ``` diff --git a/snippets/truncate-a-string.md b/snippets/truncate-a-string.md index 556667781..a33ac6367 100644 --- a/snippets/truncate-a-string.md +++ b/snippets/truncate-a-string.md @@ -5,6 +5,6 @@ Return the string truncated to the desired length, with `...` appended to the en ```js const truncate = (str, num) => - str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; + str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; // truncate('boomerang', 7) -> 'boom...' ``` From 7bee9e146e9e1d8b9c3d787a522c3ad450158d1e Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Wed, 13 Dec 2017 23:06:54 +0100 Subject: [PATCH 089/202] Add "Object to key-value pairs" --- README.md | 8 ++++++++ snippets/object-to-key-value-pairs.md | 6 ++++++ 2 files changed, 14 insertions(+) create mode 100644 snippets/object-to-key-value-pairs.md diff --git a/README.md b/README.md index b77013e78..d54c7f2d9 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ * [Measure time taken by function](#measure-time-taken-by-function) * [Median of array of numbers](#median-of-array-of-numbers) * [Object from key value pairs](#object-from-key-value-pairs) +* [Object to key value pairs](#object-to-key-value-pairs) * [Percentile](#percentile) * [Pipe](#pipe) * [Powerset](#powerset) @@ -444,6 +445,13 @@ const objectFromPairs = arr => arr.reduce((a,v) => (a[v[0]] = v[1], a), {}); // objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} ``` +### Object to key-value pairs + +```js +const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); +// objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) +``` + ### Percentile Use `Array.reduce()` to calculate how many numbers are below the value and how many are the same value and diff --git a/snippets/object-to-key-value-pairs.md b/snippets/object-to-key-value-pairs.md new file mode 100644 index 000000000..78fd63811 --- /dev/null +++ b/snippets/object-to-key-value-pairs.md @@ -0,0 +1,6 @@ +### Object to key-value pairs + +```js +const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); +// objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) +``` From a4a7eb275af0c74dd8fe28b4147391751ec68a65 Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Wed, 13 Dec 2017 23:40:27 +0100 Subject: [PATCH 090/202] Add set operations. Union, intersect and difference --- README.md | 40 ++++++++++++++++++++------- snippets/array-difference.md | 8 ++++++ snippets/array-intersection.md | 8 ++++++ snippets/array-union.md | 8 ++++++ snippets/difference-between-arrays.md | 8 ------ 5 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 snippets/array-difference.md create mode 100644 snippets/array-intersection.md create mode 100644 snippets/array-union.md delete mode 100644 snippets/difference-between-arrays.md diff --git a/README.md b/README.md index b77013e78..c66371a79 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ ## Contents * [Anagrams of string (with duplicates)](#anagrams-of-string-with-duplicates) +* [Array difference](#array-difference) +* [Array intersection](#array-intersection) +* [Array union](#array-union) * [Average of array of numbers](#average-of-array-of-numbers) * [Bottom visible](#bottom-visible) * [Capitalize first letter of every word](#capitalize-first-letter-of-every-word) @@ -21,7 +24,6 @@ * [Current URL](#current-url) * [Curry](#curry) * [Deep flatten array](#deep-flatten-array) -* [Difference between arrays](#difference-between-arrays) * [Distance between two points](#distance-between-two-points) * [Divisible by number](#divisible-by-number) * [Escape regular expression](#escape-regular-expression) @@ -85,6 +87,33 @@ const anagrams = str => { // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` +### Array difference (complement) + +Create a `Set` from `b`, then use `Array.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)); } +// difference([1,2,3], [1,2]) -> [3] +``` + +### Array intersection (Common values between two arrays) + +Create a `Set` from `b`, then use `Array.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)); } +// intersection([1,2,3], [4,3,2]) -> [2,3] +``` + +### Array union + +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])) +// union([1,2,3], [4,3,2]) -> [1,2,3,4] +``` + ### Average of array of numbers Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. @@ -211,15 +240,6 @@ const deepFlatten = arr => // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] ``` -### Difference between arrays - -Use `filter()` to remove values that are part of `values`, determined using `includes()`. - -```js -const difference = (arr, values) => arr.filter(v => !values.includes(v)); -// difference([1,2,3], [1,2]) -> [3] -``` - ### Distance between two points Use `Math.hypot()` to calculate the Euclidean distance between two points. diff --git a/snippets/array-difference.md b/snippets/array-difference.md new file mode 100644 index 000000000..74e518f5c --- /dev/null +++ b/snippets/array-difference.md @@ -0,0 +1,8 @@ +### Array difference (complement) + +Create a `Set` from `b`, then use `Array.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)); } +// difference([1,2,3], [1,2]) -> [3] +``` diff --git a/snippets/array-intersection.md b/snippets/array-intersection.md new file mode 100644 index 000000000..909c4312d --- /dev/null +++ b/snippets/array-intersection.md @@ -0,0 +1,8 @@ +### Array intersection (Common values between two arrays) + +Create a `Set` from `b`, then use `Array.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)); } +// intersection([1,2,3], [4,3,2]) -> [2,3] +``` diff --git a/snippets/array-union.md b/snippets/array-union.md new file mode 100644 index 000000000..b417dcce7 --- /dev/null +++ b/snippets/array-union.md @@ -0,0 +1,8 @@ +### Array union + +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])) +// union([1,2,3], [4,3,2]) -> [1,2,3,4] +``` diff --git a/snippets/difference-between-arrays.md b/snippets/difference-between-arrays.md deleted file mode 100644 index 1fb172dab..000000000 --- a/snippets/difference-between-arrays.md +++ /dev/null @@ -1,8 +0,0 @@ -### Difference between arrays - -Use `filter()` to remove values that are part of `values`, determined using `includes()`. - -```js -const difference = (arr, values) => arr.filter(v => !values.includes(v)); -// difference([1,2,3], [1,2]) -> [3] -``` From 13c4782c69accfdfe7b8b7f597f6c87f4770e4c8 Mon Sep 17 00:00:00 2001 From: King Date: Wed, 13 Dec 2017 17:41:24 -0500 Subject: [PATCH 091/202] update pick.md -> oneline & simpler solution --- snippets/pick.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/snippets/pick.md b/snippets/pick.md index 5523e1fe5..c3b5cd2f2 100644 --- a/snippets/pick.md +++ b/snippets/pick.md @@ -1,18 +1,9 @@ ### Pick -Use `Objexts.keys()` to convert given object to an iterable arr of keys. -Use `.filter()` to filter the given arr of keys to the expected arr of picked keys. -Use `.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair. +Use `.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. ```js -const pick = (obj, arr) => - Object - .keys(obj) - .filter((v, i) => arr.indexOf(v) !== -1 ) - .reduce((acc, cur, i) => { - acc[cur] = obj[cur]; - return acc; - }, {}); +const pick = (obj, arr) => arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); // const object = { 'a': 1, 'b': '2', 'c': 3 }; // pick(object, ['a', 'c']) -> { 'a': 1, 'c': 3 } From 383d7a57e4cfd712ff0a640aa77f7a189e55fcbd Mon Sep 17 00:00:00 2001 From: King Date: Wed, 13 Dec 2017 17:51:28 -0500 Subject: [PATCH 092/202] ran| npm run build-list --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index b77013e78..b5aef54c6 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ * [Median of array of numbers](#median-of-array-of-numbers) * [Object from key value pairs](#object-from-key-value-pairs) * [Percentile](#percentile) +* [Pick](#pick) * [Pipe](#pipe) * [Powerset](#powerset) * [Promisify](#promisify) @@ -455,6 +456,20 @@ const percentile = (arr, val) => // percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 ``` +### Pick + +Use `.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. + +```js +const pick = (obj, arr) => arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); + +// const object = { 'a': 1, 'b': '2', 'c': 3 }; +// pick(object, ['a', 'c']) -> { 'a': 1, 'c': 3 } + +// pick(object, ['a', 'c'])['a'] -> 1 +// pick(object, ['a', 'c'])['c'] -> 3 + +``` ### Pipe Use `Array.reduce()` to pass value through functions. From a0106a3c995a8c4189e71e33c25b4c82748e5910 Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Thu, 14 Dec 2017 00:00:04 +0100 Subject: [PATCH 093/202] Refactor palindrome --- README.md | 6 ++++-- snippets/check-for-palindrome.md | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b77013e78..ae83066d1 100644 --- a/README.md +++ b/README.md @@ -146,8 +146,10 @@ Convert string `toLowerCase()` and use `replace()` to remove non-alphanumeric ch Then, `split('')` into individual characters, `reverse()`, `join('')` and compare to the original, unreversed string, after converting it `tolowerCase()`. ```js -const palindrome = str => - str.toLowerCase().replace(/[\W_]/g,'').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g,''); +const palindrome = str => { + const s = str.toLowerCase().replace(/[\W_]/g,''); + return s === s.split('').reverse().join(''); +} // palindrome('taco cat') -> true ``` diff --git a/snippets/check-for-palindrome.md b/snippets/check-for-palindrome.md index bd0452cf8..a22007688 100644 --- a/snippets/check-for-palindrome.md +++ b/snippets/check-for-palindrome.md @@ -4,7 +4,9 @@ Convert string `toLowerCase()` and use `replace()` to remove non-alphanumeric ch Then, `split('')` into individual characters, `reverse()`, `join('')` and compare to the original, unreversed string, after converting it `tolowerCase()`. ```js -const palindrome = str => - str.toLowerCase().replace(/[\W_]/g,'').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g,''); +const palindrome = str => { + const s = str.toLowerCase().replace(/[\W_]/g,''); + return s === s.split('').reverse().join(''); +} // palindrome('taco cat') -> true ``` From 50f302a66c896d9393c7d9544c7eaa2e6a7d3179 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 01:17:10 +0200 Subject: [PATCH 094/202] Styleguide --- .gitignore | 2 + CONTRIBUTING.md | 79 ++++++++++-- currentSnippet.js | 3 - semi-snippets.js | 242 ----------------------------------- snippet-template.md | 4 +- snippets.js | 302 -------------------------------------------- 6 files changed, 74 insertions(+), 558 deletions(-) delete mode 100644 currentSnippet.js delete mode 100644 semi-snippets.js delete mode 100644 snippets.js diff --git a/.gitignore b/.gitignore index c2658d7d1..bc23f6a88 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ node_modules/ + +currentSnippet\.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7e90497d5..09e28829b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,74 @@ ## Contributing -You can contribute to **30 seconds of code** by sending pull requests for snippets that you find useful, reporting issues with current snippets or suggesting changes and/or additions. +**30 seconds of code** is a community effort, so feel free to contribute in any way you can. Every contribution helps! -### Guidelines for new snippets +Here's what you can do to help: -- Snippets must be short. Usually anything above 10 lines would be considered too long, but you can still submit it as it might be possible to shorten it or it might still prove useful regardless of its length. -- Snippets must be explained to a certain extent in the description above them. Make sure to include what functions you are using and why. -- Snippets must solve real-world problems and should be abstract enough to use in different scenarios. This is highly subjective, so send them in anyways. -- Snippets *should* be written in ES6 if possible. -- Snippet files must follow the anchor name conventions of [GitHub Flavored Markdown](https://github.github.com/gfm/), so that the `builder.js` can build the links for the list. -- Use the [template](snippet-template.md) to format your snippets. -- If possible, provide test cases in your Pull Request (link or comment), so that it's easier to verify that each snippet is working. +- [Open issues](https://github.com/Chalarangelo/30-seconds-of-code/issues/new) for things you want to see added or modified. +- Be part of the discussion by helping out with [existing issues](https://github.com/Chalarangelo/30-seconds-of-code/issues) or talking on our [gitter channel](https://gitter.im/30-seconds-of-code/Lobby). +- Submit [pull requests](https://github.com/Chalarangelo/30-seconds-of-code/pulls) with snippets you have created (see below for guidelines). +- Fix typos in existing snippets or run `npm run lint "snippet-name.md"` on unlinted snippets (yes, this is something we actually want help with). + +### Snippet submission and Pull request guidelines + +- **DO NOT MODIFY THE README.md FILE!** Make changes to individual snippet files. You can optionally run `npm run build-list` to update the README.md file automatically, based on the changes you have made. +- **Snippet filenames** must correspond to the title of the snippet. For example if your snippet is titled `### Awesome snippet` the filename should be `awesome-snippet.md`. + - Use `kebab-case`, not `snake_case`. + - Avoid capitalization of words, except if the whole word is capitalized (e.g `URL` should be capitalized in the filename and the snippet title). + - If there are parentheses in the title, add them to the filename (e.g. `awesome-snippet-(extra-awesome).md` if your snippet's title is `Awesome snippet (extra awesome)`). +- **Snippet titles** should have only the first letter of the first word capitalized. Certain words can be in capitals (e.g. `URL`, `RGB`), but this is on a per-snippet basis. + - All snippet titles must be prefixed with `###` and be at the very first line of your snippet. + - Snippet titles must be unique (although if you cannot find a better title, just add some placeholder at the end of the filename and title and we will figure it out). + - Follow snippet titles with an empty line. +- **Snippet descriptions** must be short and to the point. Try to explain *how* the snippet works and what Javascript features are used. Remember to include what functions you are using and why. + - Follow snippet descriptions with an empty line. +- **Snippet code** must be enclosed inside ` ```js ` and ` ``` `. + - Remember to start your snippet's code on a new line below the opening backticks. + - Use ES6 notation to define your function. For example `const myFunction = arg1, arg2 => { }`. + - Try to keep your snippets' code short and to the point. Use modern techniques and features. Make sure to test your code before submitting. + - All snippets must be followed by one (more if necessary) test case after the code, on a new line, in the form of a comment, along with the expected output. The syntax for this is `myFunction('testInput') -> 'testOutput'`. Use multiline comments only if necessary. + - Try to make your function name unique, so that it does not conflict with existing snippets. +- Snippets should be short (usually below 10 lines). If your snippet is longer than that, you can still submit it and we can help you shorten it or figure out ways to improve it. +- Snippets *should* solve real-world problems, no matter how simple. +- Snippets *should* be abstract enough to be applied to different scenarios. +- It is not mandatory, but highly appreciated if you provide **test cases** and/or performance tests (we recommend using [jsPerf](https://jsperf.com/)). +- You can start creating a new snippet, by using the [snippet template](snippet-template.md) to format your snippets. + +### Additional guidelines and conventions regarding snippets + +- When describing snippets, refer to methods, using their full name. For example, use `Array.reduce()`, instead of `reduce()`. +- If your snippet contains argument with default parameters, explain what happens if they are ommited when calling the function and what the default case is. +- If your snippet uses recursion, explain the base cases. +- Always use `const functionName` for function definitions. +- Use variables only when necessary. Prefer `const` when the values are not altered after assignment, otherwise use `let`. Avoid using `var`. +- Use `camelCase` for function and variable names if they consist of more than one word. +- Try to give meaningful names to variables. For example use `letter`, instead of `lt`. Some exceptions by convention are: + - `arr` for arrays (usually as the snippet function's argument). + - `str` for strings. + - `val` or `v` for value (usually when iterating a list, mapping, sorting etc.). + - `acc` for accumulators in `Array.reduce()`. + - `(a,b)` for the two values compared when using `Array.sort()`. + - `i` for indexes. + - `func` for function arguments. + - `nums` for arrays of numbers. +- Use `_` if your function takes no arguments or if an argument inside some function (e.g. `Array.reduce()`) is not used anywhere in your code. +- Specify default parameters for arguments, if necessary. It is preferred to put default parameters last, unless you have pretty good reason not to. +- If your snippet's function takes variadic arguments, use `..args` (although in certain cases, it might be needed to use a different name). +- If your snippet function's body is a single statement, omit the `return` keyword and use an expression instead. +- Always use soft tabs (2 spaces), never hard tabs. +- Omit curly braces (`{` and `}`) whenever possible. +- Always use single quotes for string literals. Use template literals, instead, if necessary. +- If your snippet's code is short enough (around 80 characters), you can make it a single-line function (although not mandatory). Otherwise, use multiple lines. +- Prefer using `Array` methods whenever possible. +- Prefer `Array.concat()` instead of `Array.push()` when working with `Array.reduce()`. +- Use strict equality checking (`===` and `!==` instead of `==` and `!=`), unless you specificly have reason not to. +- Prefer using the ternary operator (`condition ? trueResult : falseResult`) instead of `if else` statements whenever possible. +- Avoid nesting ternary operators (but you can do it if you feel like you should). +- You should define multiple variables on the same line (e.g. `const x = 0, y = 0`) on the same line whenever possible. +- Do not use trailing or leading underscores in variable names. +- Use dot notation (`object.property`) for object properties, when possible. Use bracket notation (`object[variable]`) when accessing object properties using a variable. +- Use arrow functions as much as possible, except when you can't. +- Use semicolons whenever necessary. If your snippet function's body is a single statement, return an expression and add a semicolon at the end. +- Leave a single space after a comma (`,`) character. +- Try to strike a balance between readability, brevity and performance. +- Never use `eval()`. Your snippet will be disqualified immediately. diff --git a/currentSnippet.js b/currentSnippet.js deleted file mode 100644 index 544a140b9..000000000 --- a/currentSnippet.js +++ /dev/null @@ -1,3 +0,0 @@ - -const valueOrDefault = (value, d) => value || d; -// valueOrDefault(NaN, 30) -> 30 diff --git a/semi-snippets.js b/semi-snippets.js deleted file mode 100644 index c35e9d6b8..000000000 --- a/semi-snippets.js +++ /dev/null @@ -1,242 +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)), []); -}; -// anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] - -const average = arr => - arr.reduce((acc, val) => acc + val, 0) / arr.length; -// average([1,2,3]) -> 2 - -const bottomVisible = _ => - document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; -// bottomVisible() -> true - -const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); -// capitalizeEveryWord('hello world!') -> 'Hello World!' - -const capitalize = (str, lowerRest = false) => - str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); -// capitalize('myName', true) -> 'Myname' - -const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); }; -/* -chainAsync([ - next => { console.log('0 seconds'); setTimeout(next, 1000); }, - next => { console.log('1 second'); setTimeout(next, 1000); }, - next => { console.log('2 seconds'); } -]) -*/ - -const palindrome = str => - str.toLowerCase().replace(/[\W_]/g, '').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g, ''); -// palindrome('taco cat') -> true - -const chunk = (arr, size) => - Array.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); -// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] - -const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); -// countOccurrences([1,1,2,1,2,3], 1) -> 3 - -const currentUrl = _ => window.location.href; -// currentUrl() -> 'https://google.com' - -const curry = (f, arity = f.length, next) => - (next = prevArgs => - nextArg => { - const args = [ ...prevArgs, nextArg ]; - return args.length >= arity ? f(...args) : next(args); - } - )([]); -// curry(Math.pow)(2)(10) -> 1024 -// curry(Math.min, 3)(10)(50)(2) -> 2 - -const deepFlatten = arr => - arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []); -// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] - -const difference = (arr, values) => arr.filter(v => !values.includes(v)); -// difference([1,2,3], [1,2]) -> [3] - -const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); -// distance(1,1, 2,3) -> 2.23606797749979 - -const isDivisible = (dividend, divisor) => dividend % divisor === 0; -// isDivisible(6,3) -> true - -const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -// escapeRegExp('(test)') -> \\(test\\) - -const isEven = num => Math.abs(num) % 2 === 0; -// isEven(3) -> false - -const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); -// factorial(6) -> 720 - -const fibonacci = n => - Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []); -// fibonacci(5) -> [0,1,1,2,3] - -const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); -// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] - -const flatten = arr => arr.reduce((a, v) => a.concat(v), []); -// flatten([1,[2],3,4]) -> [1,2,3,4] - -const arrayMax = arr => Math.max(...arr); -// arrayMax([10, 1, 5]) -> 10 - -const arrayMin = arr => Math.min(...arr); -// arrayMin([10, 1, 5]) -> 1 - -const getType = v => - v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); -// getType(new Set([1,2,3])) -> "set" - -const getScrollPos = (el = window) => - ({x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, - y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop}); -// getScrollPos() -> {x: 0, y: 200} - -const gcd = (x, y) => !y ? x : gcd(y, x % y); -// gcd (8, 36) -> 4 - -const hammingDistance = (num1, num2) => - ((num1 ^ num2).toString(2).match(/1/g) || '').length; -// hammingDistance(2,3) -> 1 - -const head = arr => arr[0]; -// head([1,2,3]) -> 1 - -const initial = arr => arr.slice(0, -1); -// initial([1,2,3]) -> [1,2] - -const initializeArrayRange = (end, start = 0) => - Array.apply(null, Array(end - start)).map((v, i) => i + start); -// initializeArrayRange(5) -> [0,1,2,3,4] - -const initializeArray = (n, value = 0) => Array(n).fill(value); -// initializeArray(5, 2) -> [2,2,2,2,2] - -const last = arr => arr.slice(-1)[0]; -// last([1,2,3]) -> 3 - -const timeTaken = callback => { - const t0 = performance.now(), r = callback(); - console.log(performance.now() - t0); - return r; -}; -// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) - -const median = arr => { - const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); - return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; -}; -// median([5,6,50,1,-5]) -> 5 -// median([0,10,-2,7]) -> 3.5 - -const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); -// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} - -const percentile = (arr, val) => - 100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; -// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 - -const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg); -// pipe(btoa, x => x.toUpperCase())("Test") -> "VGVZDA==" - -const powerset = arr => - arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); -// powerset([1,2]) -> [[], [1], [2], [2,1]] - -const promisify = func => - (...args) => - new Promise((resolve, reject) => - func(...args, (err, result) => - err ? reject(err) : resolve(result)) - ); -// const delay = promisify((d, cb) => setTimeout(cb, d)) -// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s - -const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; -// randomIntegerInRange(0, 5) -> 2 - -const randomInRange = (min, max) => Math.random() * (max - min) + min; -// randomInRange(2,10) -> 6.0211363285087005 - -const randomizeOrder = arr => arr.sort((a, b) => Math.random() >= 0.5 ? -1 : 1); -// randomizeOrder([1,2,3]) -> [1,3,2] - -const redirect = (url, asLink = true) => - asLink ? window.location.href = url : window.location.replace(url); -// redirect('https://google.com') - -const reverseString = str => [...str].reverse().join(''); -// reverseString('foobar') -> 'raboof' - -const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); -// rgbToHex(255, 165, 1) -> 'ffa501' - -const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); -// const delay = (d) => new Promise(r => setTimeout(r, d)) -// series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete - -const scrollToTop = _ => { - const c = document.documentElement.scrollTop || document.body.scrollTop; - if (c > 0) { - window.requestAnimationFrame(scrollToTop); - window.scrollTo(0, c - c / 8); - } -}; -// scrollToTop() - -const shuffle = arr => { - let r = arr.map(Math.random); - return arr.sort((a, b) => r[a] - r[b]); -}; -// shuffle([1,2,3]) -> [2, 1, 3] - -const similarity = (arr, values) => arr.filter(v => values.includes(v)); -// similarity([1,2,3], [1,2,4]) -> [1,2] - -const sortCharactersInString = str => - str.split('').sort((a, b) => a.localeCompare(b)).join(''); -// sortCharactersInString('cabbage') -> 'aabbceg' - -const sum = arr => arr.reduce((acc, val) => acc + val, 0); -// sum([1,2,3,4]) -> 10 - -[varA, varB] = [varB, varA]; -// [x, y] = [y, x] - -const tail = arr => arr.length > 1 ? arr.slice(1) : arr; -// tail([1,2,3]) -> [2,3] -// tail([1]) -> [1] - -const truncate = (str, num) => - str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; -// truncate('boomerang', 7) -> 'boom...' - -const unique = arr => [...new Set(arr)]; -// unique([1,2,2,3,4,4,5]) -> [1,2,3,4,5] - -const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))?/g).reduce( - (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} - ); -// getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} - -const uuid = _ => - ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => - (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) - ); -// uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' - -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); -// validateNumber('10') -> true - -const valueOrDefault = (value, d) => value || d; -// valueOrDefault(NaN, 30) -> 30 diff --git a/snippet-template.md b/snippet-template.md index e258fe079..83e820965 100644 --- a/snippet-template.md +++ b/snippet-template.md @@ -1,9 +1,9 @@ ### Snippet title -Explain briefly how the snippet works +Explain briefly how the snippet works. ```js -const functionName = arguments => +const functionName = arguments => {functionBody} // functionName(sampleInput) -> sampleOutput ``` diff --git a/snippets.js b/snippets.js deleted file mode 100644 index d754bf389..000000000 --- a/snippets.js +++ /dev/null @@ -1,302 +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 )), []); -} -// anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] - - -const average = arr => - arr.reduce( (acc , val) => acc + val, 0) / arr.length; -// average([1,2,3]) -> 2 - - -const bottomVisible = _ => - document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; -// bottomVisible() -> true - - -const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); -// capitalizeEveryWord('hello world!') -> 'Hello World!' - - -const capitalize = (str, lowerRest = false) => - str.slice(0, 1).toUpperCase() + (lowerRest? str.slice(1).toLowerCase() : str.slice(1)); -// capitalize('myName', true) -> 'Myname' - - -const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); } -/* -chainAsync([ - next => { console.log('0 seconds'); setTimeout(next, 1000); }, - next => { console.log('1 second'); setTimeout(next, 1000); }, - next => { console.log('2 seconds'); } -]) -*/ - - -const palindrome = str => - str.toLowerCase().replace(/[\W_]/g,'').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g,''); -// palindrome('taco cat') -> true - - -const chunk = (arr, size) => - Array.apply(null, {length: Math.ceil(arr.length/size)}).map((v, i) => arr.slice(i*size, i*size+size)); -// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] - - -const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); -// countOccurrences([1,1,2,1,2,3], 1) -> 3 - - -const currentUrl = _ => window.location.href; -// currentUrl() -> 'https://google.com' - - -const curry = (f, arity = f.length, next) => - (next = prevArgs => - nextArg => { - const args = [ ...prevArgs, nextArg ]; - return args.length >= arity ? f(...args) : next(args); - } - )([]); -// curry(Math.pow)(2)(10) -> 1024 -// curry(Math.min, 3)(10)(50)(2) -> 2 - - -const deepFlatten = arr => - arr.reduce( (a, v) => a.concat( Array.isArray(v) ? deepFlatten(v) : v ), []); -// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] - - -const difference = (arr, values) => arr.filter(v => !values.includes(v)); -// difference([1,2,3], [1,2]) -> [3] - - -const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); -// distance(1,1, 2,3) -> 2.23606797749979 - - -const isDivisible = (dividend, divisor) => dividend % divisor === 0; -// isDivisible(6,3) -> true - - -const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -// escapeRegExp('(test)') -> \\(test\\) - - -const isEven = num => Math.abs(num) % 2 === 0; -// isEven(3) -> false - - -const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); -// factorial(6) -> 720 - - -const fibonacci = n => - Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),[]); -// fibonacci(5) -> [0,1,1,2,3] - - -const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); -// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] - - -const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); -// flatten([1,[2],3,4]) -> [1,2,3,4] - - -const arrayMax = arr => Math.max(...arr); -// arrayMax([10, 1, 5]) -> 10 - - -const arrayMin = arr => Math.min(...arr); -// arrayMin([10, 1, 5]) -> 1 - - -const getType = v => - v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); -// getType(new Set([1,2,3])) -> "set" - - -const getScrollPos = (el = window) => - ( {x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, - y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop} ); -// getScrollPos() -> {x: 0, y: 200} - - -const gcd = (x , y) => !y ? x : gcd(y, x % y); -// gcd (8, 36) -> 4 - - -const hammingDistance = (num1, num2) => - ((num1^num2).toString(2).match(/1/g) || '').length; -// hammingDistance(2,3) -> 1 - - -const head = arr => arr[0]; -// head([1,2,3]) -> 1 - - -const initial = arr => arr.slice(0,-1); -// initial([1,2,3]) -> [1,2] - - -const initializeArrayRange = (end, start = 0) => - Array.apply(null, Array(end-start)).map( (v,i) => i + start ); -// initializeArrayRange(5) -> [0,1,2,3,4] - - -const initializeArray = (n, value = 0) => Array(n).fill(value); -// initializeArray(5, 2) -> [2,2,2,2,2] - - -const last = arr => arr.slice(-1)[0]; -// last([1,2,3]) -> 3 - - -const timeTaken = callback => { - const t0 = performance.now(), r = callback(); - console.log(performance.now() - t0); - return r; -} -// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) - - -const median = arr => { - const mid = Math.floor(arr.length / 2), nums = arr.sort((a,b) => a - b); - return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; -} -// median([5,6,50,1,-5]) -> 5 -// median([0,10,-2,7]) -> 3.5 - - -const objectFromPairs = arr => arr.reduce((a,v) => (a[v[0]] = v[1], a), {}); -// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} - - -const percentile = (arr, val) => - 100 * arr.reduce((acc,v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; -// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 - - -const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg); -// pipe(btoa, x => x.toUpperCase())("Test") -> "VGVZDA==" - - -const powerset = arr => - arr.reduce( (a,v) => a.concat(a.map( r => [v].concat(r) )), [[]]); -// powerset([1,2]) -> [[], [1], [2], [2,1]] - - -const promisify = func => - (...args) => - new Promise((resolve, reject) => - func(...args, (err, result) => - err ? reject(err) : resolve(result)) - ); -// const delay = promisify((d, cb) => setTimeout(cb, d)) -// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s - - -const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; -// randomIntegerInRange(0, 5) -> 2 - - -const randomInRange = (min, max) => Math.random() * (max - min) + min; -// randomInRange(2,10) -> 6.0211363285087005 - - -const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); -// randomizeOrder([1,2,3]) -> [1,3,2] - - -const redirect = (url, asLink = true) => - asLink ? window.location.href = url : window.location.replace(url); -// redirect('https://google.com') - - -const reverseString = str => [...str].reverse().join(''); -// reverseString('foobar') -> 'raboof' - - -const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); -// rgbToHex(255, 165, 1) -> 'ffa501' - - -const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); -// const delay = (d) => new Promise(r => setTimeout(r, d)) -// series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete - - -const scrollToTop = _ => { - const c = document.documentElement.scrollTop || document.body.scrollTop; - if(c > 0) { - window.requestAnimationFrame(scrollToTop); - window.scrollTo(0, c - c/8); - } -} -// scrollToTop() - - -const shuffle = arr => { - let r = arr.map(Math.random); - return arr.sort((a,b) => r[a] - r[b]); -} -// shuffle([1,2,3]) -> [2, 1, 3] - - -const similarity = (arr, values) => arr.filter(v => values.includes(v)); -// similarity([1,2,3], [1,2,4]) -> [1,2] - - -const sortCharactersInString = str => - str.split('').sort( (a,b) => a.localeCompare(b) ).join(''); -// sortCharactersInString('cabbage') -> 'aabbceg' - - -const sum = arr => arr.reduce( (acc , val) => acc + val, 0); -// sum([1,2,3,4]) -> 10 - - -[varA, varB] = [varB, varA]; -// [x, y] = [y, x] - - -const tail = arr => arr.length > 1 ? arr.slice(1) : arr; -// tail([1,2,3]) -> [2,3] -// tail([1]) -> [1] - - -const truncate = (str, num) => - str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; -// truncate('boomerang', 7) -> 'boom...' - - -const unique = arr => [...new Set(arr)]; -// unique([1,2,2,3,4,4,5]) -> [1,2,3,4,5] - - -const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))?/g).reduce( - (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')+1), a), {} - ); -// getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} - - -const uuid = _ => - ( [1e7]+-1e3+-4e3+-8e3+-1e11 ).replace( /[018]/g, c => - (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) - ); -// uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' - - -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); -// validateNumber('10') -> true - - -const valueOrDefault = (value, d) => value || d; -// valueOrDefault(NaN, 30) -> 30 - - From e7252bb7deeb79bfec2d5ef853f30d361dd9a2d4 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 01:34:24 +0200 Subject: [PATCH 095/202] Lint pick, build README --- README.md | 13 +++++-------- snippets/pick.md | 14 +++++--------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 332fba4bc..21d6bafb2 100644 --- a/README.md +++ b/README.md @@ -457,18 +457,15 @@ const percentile = (arr, val) => ### Pick -Use `.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. +Use `Array.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. ```js -const pick = (obj, arr) => arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); - -// const object = { 'a': 1, 'b': '2', 'c': 3 }; -// pick(object, ['a', 'c']) -> { 'a': 1, 'c': 3 } - +const pick = (obj, arr) => + arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); +// pick({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c']) -> { 'a': 1, 'c': 3 } // pick(object, ['a', 'c'])['a'] -> 1 -// pick(object, ['a', 'c'])['c'] -> 3 - ``` + ### Pipe Use `Array.reduce()` to pass value through functions. diff --git a/snippets/pick.md b/snippets/pick.md index c3b5cd2f2..3689e4a28 100644 --- a/snippets/pick.md +++ b/snippets/pick.md @@ -1,14 +1,10 @@ ### Pick -Use `.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. +Use `Array.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. ```js -const pick = (obj, arr) => arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); - -// const object = { 'a': 1, 'b': '2', 'c': 3 }; -// pick(object, ['a', 'c']) -> { 'a': 1, 'c': 3 } - +const pick = (obj, arr) => + arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); +// pick({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c']) -> { 'a': 1, 'c': 3 } // pick(object, ['a', 'c'])['a'] -> 1 -// pick(object, ['a', 'c'])['c'] -> 3 - -``` \ No newline at end of file +``` From 24468a0afff3dfcca197bf299f5331d8bbec52d8 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 01:46:30 +0200 Subject: [PATCH 096/202] Object to key-value pairs description, linting, build README --- README.md | 2 ++ snippets/object-to-key-value-pairs.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 2cd816916..b449e0318 100644 --- a/README.md +++ b/README.md @@ -447,6 +447,8 @@ const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); ### Object to key-value pairs +Use `Object.keys()` and `Array.map()` to iterate over the object's keys and produce an array with key-value pairs. + ```js const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); // objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) diff --git a/snippets/object-to-key-value-pairs.md b/snippets/object-to-key-value-pairs.md index 78fd63811..fb639e432 100644 --- a/snippets/object-to-key-value-pairs.md +++ b/snippets/object-to-key-value-pairs.md @@ -1,5 +1,7 @@ ### Object to key-value pairs +Use `Object.keys()` and `Array.map()` to iterate over the object's keys and produce an array with key-value pairs. + ```js const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); // objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) From 2b34ee4ba92f13c0b0d4f653e8e2fde7f1ca2601 Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Thu, 14 Dec 2017 01:11:38 +0100 Subject: [PATCH 097/202] Fix names and links --- README.md | 6 +++--- snippets/array-difference.md | 2 +- snippets/array-intersection.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ddd428064..7ccd59b50 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -89,7 +89,7 @@ const anagrams = str => { // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` -### Array difference (complement) +### Array difference Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. @@ -98,7 +98,7 @@ const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has // difference([1,2,3], [1,2]) -> [3] ``` -### Array intersection (Common values between two arrays) +### Array intersection Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. diff --git a/snippets/array-difference.md b/snippets/array-difference.md index 74e518f5c..46469b1d6 100644 --- a/snippets/array-difference.md +++ b/snippets/array-difference.md @@ -1,4 +1,4 @@ -### Array difference (complement) +### Array difference Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. diff --git a/snippets/array-intersection.md b/snippets/array-intersection.md index 909c4312d..87c42378b 100644 --- a/snippets/array-intersection.md +++ b/snippets/array-intersection.md @@ -1,4 +1,4 @@ -### Array intersection (Common values between two arrays) +### Array intersection Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. From 38596dcaa53e54ff087c802b847c62b54f671b5b Mon Sep 17 00:00:00 2001 From: Michael Goldspinner Date: Wed, 13 Dec 2017 23:53:34 -0500 Subject: [PATCH 098/202] Ordinal Suffix hotfix mismatched variables. --- snippets/get-ordinal-suffix-of-number.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/get-ordinal-suffix-of-number.md b/snippets/get-ordinal-suffix-of-number.md index cda41b9ac..725ff05b4 100644 --- a/snippets/get-ordinal-suffix-of-number.md +++ b/snippets/get-ordinal-suffix-of-number.md @@ -12,7 +12,7 @@ const toOrdinalSuffix = int => { var oPattern = [1,2,3,4]; var tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] - return pattern.includes(digits[0]) && !teens.includes(digits[1]) ? int + suffix[digits[0]-1] : int + suffix[3]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; } // toOrdinalSuffix("123") -> "123rd" ``` \ No newline at end of file From 5fbfa9422c7fc29ac20e0a6b58bfc4f2e63d440f Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Wed, 13 Dec 2017 21:20:36 -0800 Subject: [PATCH 099/202] Update README.md Remove the Question mark as per https://github.com/Chalarangelo/30-seconds-of-code/issues/95 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ddd428064..3dc91bb5e 100644 --- a/README.md +++ b/README.md @@ -705,7 +705,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + url.match(/([^?=&]+)(=([^&]*))/g).reduce( (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} From e421b1d49d92c1a95a30fe6fa7b157ea4a3426dd Mon Sep 17 00:00:00 2001 From: panshao <1016432619@qq.com> Date: Thu, 14 Dec 2017 14:09:46 +0800 Subject: [PATCH 100/202] Update README.md use Array.from instead of Array.apply --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ddd428064..46f4ff8e9 100644 --- a/README.md +++ b/README.md @@ -185,14 +185,14 @@ const palindrome = str => { ### Chunk array -Use `Array.apply()` to create a new array, that fits the number of chunks that will be produced. -Use `Array.map()` to map each element of the new array to a chunk the length of `size`. +Use `Array.from(arrayLike[, mapFn[, thisArg]])` to create a new array, that fits the number of chunks that will be produced. +Use `mapFn` 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.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); -// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] + Array.from({length: Math.ceil(arr.length / size)}, (v, i) => arr.slice(i * size, i * size + size)); + // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` ### Count occurrences of a value in array From 5f7add56646d421d977af162498a81a1c8559e4f Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 01:19:15 -0500 Subject: [PATCH 101/202] add compact.md & ran npm run build-list --- README.md | 11 ++++++++++- snippets/compact.md | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 snippets/compact.md diff --git a/README.md b/README.md index ddd428064..3d2cc38a8 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ * [Chain asynchronous functions](#chain-asynchronous-functions) * [Check for palindrome](#check-for-palindrome) * [Chunk array](#chunk-array) +* [Compact](#compact) * [Count occurrences of a value in array](#count-occurrences-of-a-value-in-array) * [Current URL](#current-url) * [Curry](#curry) @@ -55,7 +56,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -195,6 +196,14 @@ const chunk = (arr, size) => // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` +### Compact + +Use `.filter()` to filter falsey values. For example false, null, 0, "", undefined, and NaN are falsey. + +```js +const compact = (arr) => arr.filter( v => [0, null, false, '', undefined].indexOf(v) === -1 && v); +// compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] +``` ### Count occurrences of a value in array Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. diff --git a/snippets/compact.md b/snippets/compact.md new file mode 100644 index 000000000..de76f834b --- /dev/null +++ b/snippets/compact.md @@ -0,0 +1,8 @@ +### Compact + +Use `.filter()` to filter falsey values. For example false, null, 0, "", undefined, and NaN are falsey. + +```js +const compact = (arr) => arr.filter( v => [0, null, false, '', undefined].indexOf(v) === -1 && v); +// compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] +``` \ No newline at end of file From b6f19c47c20d917bbc03c06ebc1041ccd051eac3 Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Wed, 13 Dec 2017 23:53:53 -0800 Subject: [PATCH 102/202] Fix: validateNumber: check cooercian now passes all 16 test cases --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ddd428064..261ff99a6 100644 --- a/README.md +++ b/README.md @@ -729,7 +729,7 @@ Use `!isNaN` in combination with `parseFloat()` to check if the argument is a nu Use `isFinite()` to check if the number is finite. ```js -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; // validateNumber('10') -> true ``` From e8347a46782b68734138d79917ab6793b22ca91e Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 02:56:47 -0500 Subject: [PATCH 103/202] refactor & elegant solution --- snippets/compact.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/compact.md b/snippets/compact.md index de76f834b..92dd9b767 100644 --- a/snippets/compact.md +++ b/snippets/compact.md @@ -3,6 +3,6 @@ Use `.filter()` to filter falsey values. For example false, null, 0, "", undefined, and NaN are falsey. ```js -const compact = (arr) => arr.filter( v => [0, null, false, '', undefined].indexOf(v) === -1 && v); +const compact = (arr) => arr.filter(v => v); // compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] ``` \ No newline at end of file From 81f7e8e9ed5564859b9a33813a7b371ec3cede1e Mon Sep 17 00:00:00 2001 From: Huseyin Sekmenoglu Date: Thu, 14 Dec 2017 10:57:17 +0300 Subject: [PATCH 104/202] Create validate-email.md --- snippets/validate-email.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 snippets/validate-email.md diff --git a/snippets/validate-email.md b/snippets/validate-email.md new file mode 100644 index 000000000..57a8afd2a --- /dev/null +++ b/snippets/validate-email.md @@ -0,0 +1,10 @@ +### Validate Email + + Regex is taken from https://stackoverflow.com/questions/46155/how-to-validate-email-address-in-javascript + Returns `true` if email is valid, `false` if not. + + ```js + const validateEmail = str => /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(str); + // isemail(mymail@gmail.com) -> true + ``` + From 0c5f677688a5ea8ae598e27ea7b879ccb6db0d0a Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 03:00:29 -0500 Subject: [PATCH 105/202] ran npm run build-list --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d2cc38a8..31007af89 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ const chunk = (arr, size) => Use `.filter()` to filter falsey values. For example false, null, 0, "", undefined, and NaN are falsey. ```js -const compact = (arr) => arr.filter( v => [0, null, false, '', undefined].indexOf(v) === -1 && v); +const compact = (arr) => arr.filter(v => v); // compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] ``` ### Count occurrences of a value in array From 2903ece39bbe619e347a2d26ab3d54827bc4dcea Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:06:13 +0200 Subject: [PATCH 106/202] Update compact.md Updated description a little. --- snippets/compact.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/snippets/compact.md b/snippets/compact.md index 92dd9b767..607634b4a 100644 --- a/snippets/compact.md +++ b/snippets/compact.md @@ -1,8 +1,8 @@ ### Compact -Use `.filter()` to filter falsey values. For example false, null, 0, "", undefined, and NaN are falsey. +Use `Array.filter()` to filter out falsey values (`false`, `null`, `0`, `""`, `undefined`, and `NaN`). ```js const compact = (arr) => arr.filter(v => v); // compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] -``` \ No newline at end of file +``` From 5fe1485d64ae245b0741e2f434891d97aac75252 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:07:14 +0200 Subject: [PATCH 107/202] Build README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 31007af89..b23877de1 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -198,12 +198,13 @@ const chunk = (arr, size) => ### Compact -Use `.filter()` to filter falsey values. For example false, null, 0, "", undefined, and NaN are falsey. +Use `Array.filter()` to filter out falsey values (`false`, `null`, `0`, `""`, `undefined`, and `NaN`). ```js const compact = (arr) => arr.filter(v => v); // compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] ``` + ### Count occurrences of a value in array Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. From d563b73b7d6d9bea5fd9d51b46db59c7f83e364f Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Wed, 13 Dec 2017 23:53:53 -0800 Subject: [PATCH 108/202] Revert "Fix: validateNumber: check cooercian" This reverts commit d66511410af1bbb9c479791606ed631ca4dd203a. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 261ff99a6..ddd428064 100644 --- a/README.md +++ b/README.md @@ -729,7 +729,7 @@ Use `!isNaN` in combination with `parseFloat()` to check if the argument is a nu Use `isFinite()` to check if the number is finite. ```js -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); // validateNumber('10') -> true ``` From 960fa239bcb1d91976643d899abcd4b424866b7d Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:15:43 +0200 Subject: [PATCH 109/202] Update get-ordinal-suffix-of-number.md --- snippets/get-ordinal-suffix-of-number.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/snippets/get-ordinal-suffix-of-number.md b/snippets/get-ordinal-suffix-of-number.md index 725ff05b4..f8832638b 100644 --- a/snippets/get-ordinal-suffix-of-number.md +++ b/snippets/get-ordinal-suffix-of-number.md @@ -5,14 +5,11 @@ Find which ordinal pattern digits match. If digit is found in teens pattern, use teens ordinal. ```js -const toOrdinalSuffix = int => { - int = parseInt(int); - var digits = [ (int % 10), (int % 100)]; - var ordinals = ["st", "nd", "rd", "th"]; - var oPattern = [1,2,3,4]; - var tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] - - return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; +const toOrdinalSuffix = num => { + const int = parseInt(num), digits = [(int % 10), (int % 100)], + ordinals = ["st", "nd", "rd", "th"], oPattern = [1,2,3,4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; } // toOrdinalSuffix("123") -> "123rd" -``` \ No newline at end of file +``` From 465935215f588df85aeeba935a4223c887b05aa9 Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Thu, 14 Dec 2017 00:15:57 -0800 Subject: [PATCH 110/202] Fix: do the change in the individual .md file --- snippets/validate-number.md | 1 + 1 file changed, 1 insertion(+) diff --git a/snippets/validate-number.md b/snippets/validate-number.md index a26eca627..2e2b3f970 100644 --- a/snippets/validate-number.md +++ b/snippets/validate-number.md @@ -2,6 +2,7 @@ Use `!isNaN` in combination with `parseFloat()` to check if the argument is a number. Use `isFinite()` to check if the number is finite. +Use `Number()` to check if the coercion holds. ```js const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); From f37272cd01f7b8ddb8e7354167dfc685bf551bd3 Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Thu, 14 Dec 2017 00:17:19 -0800 Subject: [PATCH 111/202] Fix: actually update the code snippet, not just the blurb --- snippets/validate-number.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/validate-number.md b/snippets/validate-number.md index 2e2b3f970..60a037e3e 100644 --- a/snippets/validate-number.md +++ b/snippets/validate-number.md @@ -5,6 +5,6 @@ Use `isFinite()` to check if the number is finite. Use `Number()` to check if the coercion holds. ```js -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; // validateNumber('10') -> true ``` From aac891ad96adcf51ed4f1c0c64f17aced67402d3 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:17:37 +0200 Subject: [PATCH 112/202] Build README --- README.md | 17 +++++++++++++++++ ...of-number.md => ordinal-suffix-of-number.md} | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) rename snippets/{get-ordinal-suffix-of-number.md => ordinal-suffix-of-number.md} (94%) diff --git a/README.md b/README.md index b23877de1..ee07a577e 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ * [Median of array of numbers](#median-of-array-of-numbers) * [Object from key value pairs](#object-from-key-value-pairs) * [Object to key value pairs](#object-to-key-value-pairs) +* [Ordinal suffix of number](#ordinal-suffix-of-number) * [Percentile](#percentile) * [Pick](#pick) * [Pipe](#pipe) @@ -486,6 +487,22 @@ const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); // objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) ``` +### Ordinal suffix of number + +Use the modulo operator (`%`) to find values of single and tens digits. +Find which ordinal pattern digits match. +If digit is found in teens pattern, use teens ordinal. + +```js +const toOrdinalSuffix = num => { + const int = parseInt(num), digits = [(int % 10), (int % 100)], + ordinals = ["st", "nd", "rd", "th"], oPattern = [1,2,3,4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; +} +// toOrdinalSuffix("123") -> "123rd" +``` + ### Percentile Use `Array.reduce()` to calculate how many numbers are below the value and how many are the same value and diff --git a/snippets/get-ordinal-suffix-of-number.md b/snippets/ordinal-suffix-of-number.md similarity index 94% rename from snippets/get-ordinal-suffix-of-number.md rename to snippets/ordinal-suffix-of-number.md index f8832638b..4e849eff7 100644 --- a/snippets/get-ordinal-suffix-of-number.md +++ b/snippets/ordinal-suffix-of-number.md @@ -1,4 +1,4 @@ -### Get Ordinal Suffix of Number +### Ordinal suffix of number Use the modulo operator (`%`) to find values of single and tens digits. Find which ordinal pattern digits match. From 9e63ad8975ea01f0d6623a1468e023422d6a9cc8 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:21:18 +0200 Subject: [PATCH 113/202] Build README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ee07a577e..458bf5611 100644 --- a/README.md +++ b/README.md @@ -754,9 +754,10 @@ const uuid = _ => Use `!isNaN` in combination with `parseFloat()` to check if the argument is a number. Use `isFinite()` to check if the number is finite. +Use `Number()` to check if the coercion holds. ```js -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; // validateNumber('10') -> true ``` From 494189089e7c760da4bde2e65c6d5ed8f81793c3 Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Wed, 13 Dec 2017 21:20:36 -0800 Subject: [PATCH 114/202] Revert "Update README.md" This reverts commit 682f172645a7b16f640f966f25b02de0cd12f55b. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3dc91bb5e..ddd428064 100644 --- a/README.md +++ b/README.md @@ -705,7 +705,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))/g).reduce( + url.match(/([^?=&]+)(=([^&]*))?/g).reduce( (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} From e6bfe6606f9ef20468d667cadd7a478bcf80cede Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Thu, 14 Dec 2017 00:23:14 -0800 Subject: [PATCH 115/202] Fix: remove one or more quantifier from Match to properly pull out parts --- snippets/URL-parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/URL-parameters.md b/snippets/URL-parameters.md index 742e7ffbd..f78c774d8 100644 --- a/snippets/URL-parameters.md +++ b/snippets/URL-parameters.md @@ -5,7 +5,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + url.match(/([^?=&]+)(=([^&]*))/g).reduce( (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} From 3fae1fa34a953bf262f02fc9ed69df7ac34d4553 Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 03:24:05 -0500 Subject: [PATCH 116/202] update description of head & ran npm run build-list --- README.md | 4 ++-- snippets/head-of-list.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 458bf5611..c26a5677d 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -395,7 +395,7 @@ const hammingDistance = (num1, num2) => ### Head of list -Return `arr[0]`. +Use `arr[0]` to return the first element of the passed array. ```js const head = arr => arr[0]; diff --git a/snippets/head-of-list.md b/snippets/head-of-list.md index 31dc5fbaf..c2e0d5a3a 100644 --- a/snippets/head-of-list.md +++ b/snippets/head-of-list.md @@ -1,6 +1,6 @@ ### Head of list -Return `arr[0]`. +Use `arr[0]` to return the first element of the passed array. ```js const head = arr => arr[0]; From 3ce9c180c59c35a0446c1296cf9072ebf93e5b60 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:26:08 +0200 Subject: [PATCH 117/202] Build README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a125ed5c6..850d944cf 100644 --- a/README.md +++ b/README.md @@ -732,7 +732,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + url.match(/([^?=&]+)(=([^&]*))/g).reduce( (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} From 80af3e7c6d06b9baa743b477226b675b4391880e Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:28:09 +0200 Subject: [PATCH 118/202] Build README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af1cd5ccb..4dbfe200a 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) From e98fd5fe3ab0aa76168d5898ca51d813c5f67df5 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:32:59 +0200 Subject: [PATCH 119/202] Build README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 476f862a9..88d89840c 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) From 27c02041fd0ed0afc685d5d771cd31d440689afa Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:35:58 +0200 Subject: [PATCH 120/202] Build README --- README.md | 16 ++++++++++++++++ snippets/sleep.md | 12 +++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 88d89840c..8b9c31e13 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ * [Scroll to top](#scroll-to-top) * [Shuffle array values](#shuffle-array-values) * [Similarity between arrays](#similarity-between-arrays) +* [Sleep](#sleep) * [Sort characters in string (alphabetical)](#sort-characters-in-string-alphabetical) * [Sum of array of numbers](#sum-of-array-of-numbers) * [Swap values of two variables](#swap-values-of-two-variables) @@ -667,6 +668,21 @@ const similarity = (arr, values) => arr.filter(v => values.includes(v)); // similarity([1,2,3], [1,2,4]) -> [1,2] ``` +### Sleep + +Delay executing part of an `async` function, by putting it to sleep, returning a `Promise`. + +```js +const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); +/* +async function sleepyWork() { + console.log('I\'m going to sleep for 1 second.'); + await sleep(1000); + console.log('I woke up after 1 second.'); +} +*/ +``` + ### Sort characters in string (alphabetical) Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, recombine using `join('')`. diff --git a/snippets/sleep.md b/snippets/sleep.md index c64ed3917..e2a58d0bd 100644 --- a/snippets/sleep.md +++ b/snippets/sleep.md @@ -4,9 +4,11 @@ Delay executing part of an `async` function, by putting it to sleep, returning a ```js const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); -// async function sleepyWork() { -// console.log('I\'m going to sleep for 1 second.'); -// await sleep(1000); -// console.log('I woke up after 1 second.'); -// } +/* +async function sleepyWork() { + console.log('I\'m going to sleep for 1 second.'); + await sleep(1000); + console.log('I woke up after 1 second.'); +} +*/ ``` From 755425f5562215404aef5cd59a9d00eeb16246de Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 03:44:45 -0500 Subject: [PATCH 121/202] ran npm run build-list & update intial-of-list description --- README.md | 4 ++-- snippets/initial-of-list.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8b9c31e13..f370a585a 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -405,7 +405,7 @@ const head = arr => arr[0]; ### Initial of list -Return `arr.slice(0,-1)`. +Use `arr.slice(0,-1)`to return all but the last element of the array. ```js const initial = arr => arr.slice(0, -1); diff --git a/snippets/initial-of-list.md b/snippets/initial-of-list.md index a222f2306..1f967f804 100644 --- a/snippets/initial-of-list.md +++ b/snippets/initial-of-list.md @@ -1,6 +1,6 @@ ### Initial of list -Return `arr.slice(0,-1)`. +Use `arr.slice(0,-1)`to return all but the last element of the array. ```js const initial = arr => arr.slice(0, -1); From 91f393207df999ed0ef1cf715f08426d570bd426 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:45:09 +0200 Subject: [PATCH 122/202] Update group-by Shortened code. It now also follows the styleguide more precisely. Improved description. --- snippets/group-by | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/snippets/group-by b/snippets/group-by index 53383db3a..e6df1a2a7 100644 --- a/snippets/group-by +++ b/snippets/group-by @@ -1,16 +1,14 @@ ### Group by -Passing an array of values, a function or a property name thats going to be run against each value in the array, -returns an object where the keys are the mapped results and the values is an array of the original values that generated the same results. +Use `Array.map()` to map the values of an array to a function or property name. +Use `Array.reduce()` to create an object, where the keys are produced from the mapped results. ```js -const groupBy = (values, fn) => { - return (typeof fn === 'function' ? values.map(fn) : values.map((val) => val[fn])) +const groupBy = (arr, func) => + (typeof func === 'function' ? arr.map(func) : arr.map(val => val[func])) .reduce((acc, val, i) => { - acc[val] = acc[val] === undefined ? [values[i]] : acc[val].concat(values[i]); - return acc; + acc[val] = acc[val] === undefined ? [arr[i]] : acc[val].concat(arr[i]); return acc; }, {}); -} // groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]} // groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} ``` From 2afdce90ee3d55ce14ce9a8d8e0bb7614e1accc3 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:46:46 +0200 Subject: [PATCH 123/202] Build README --- README.md | 16 ++++++++++++++++ snippets/{group-by => group-by.md} | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) rename snippets/{group-by => group-by.md} (94%) diff --git a/README.md b/README.md index 8b9c31e13..522f36584 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ * [Get native type of value](#get-native-type-of-value) * [Get scroll position](#get-scroll-position) * [Greatest common divisor (GCD)](#greatest-common-divisor-gcd) +* [Group by](#group-by) * [Hamming distance](#hamming-distance) * [Head of list](#head-of-list) * [Initial of list](#initial-of-list) @@ -383,6 +384,21 @@ const gcd = (x, y) => !y ? x : gcd(y, x % y); // gcd (8, 36) -> 4 ``` +### Group by + +Use `Array.map()` to map the values of an array to a function or property name. +Use `Array.reduce()` to create an object, where the keys are produced from the mapped results. + +```js +const groupBy = (arr, func) => + (typeof func === 'function' ? arr.map(func) : arr.map(val => val[func])) + .reduce((acc, val, i) => { + acc[val] = acc[val] === undefined ? [arr[i]] : acc[val].concat(arr[i]); return acc; + }, {}); +// groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]} +// groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} +``` + ### Hamming distance Use XOR operator (`^`) to find the bit difference between the two numbers, convert to binary string using `toString(2)`. diff --git a/snippets/group-by b/snippets/group-by.md similarity index 94% rename from snippets/group-by rename to snippets/group-by.md index e6df1a2a7..ab833c9d2 100644 --- a/snippets/group-by +++ b/snippets/group-by.md @@ -4,7 +4,7 @@ Use `Array.map()` to map the values of an array to a function or property name. Use `Array.reduce()` to create an object, where the keys are produced from the mapped results. ```js -const groupBy = (arr, func) => +const groupBy = (arr, func) => (typeof func === 'function' ? arr.map(func) : arr.map(val => val[func])) .reduce((acc, val, i) => { acc[val] = acc[val] === undefined ? [arr[i]] : acc[val].concat(arr[i]); return acc; From 2123d8d50a72b26003f1d8525426c84265cab871 Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 03:49:18 -0500 Subject: [PATCH 124/202] update last-of-list & ran npm run build-list --- README.md | 4 ++-- snippets/last-of-list.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8b9c31e13..d267e205a 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -435,7 +435,7 @@ const initializeArray = (n, value = 0) => Array(n).fill(value); ### Last of list -Return `arr.slice(-1)[0]`. +Use `arr.slice(-1)[0]` to get the last element of the given array. ```js const last = arr => arr.slice(-1)[0]; diff --git a/snippets/last-of-list.md b/snippets/last-of-list.md index 16955f201..d27b0b35e 100644 --- a/snippets/last-of-list.md +++ b/snippets/last-of-list.md @@ -1,6 +1,6 @@ ### Last of list -Return `arr.slice(-1)[0]`. +Use `arr.slice(-1)[0]` to get the last element of the given array. ```js const last = arr => arr.slice(-1)[0]; From 3b0fa08fdd5052e15759c92263218449d0d1b5f7 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:59:20 +0200 Subject: [PATCH 125/202] Build README --- README.md | 8 ++++---- snippets/chunk-array.md | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e3d9727df..dd66eebff 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -189,14 +189,14 @@ const palindrome = str => { ### Chunk array -Use `Array.from(arrayLike[, mapFn[, thisArg]])` to create a new array, that fits the number of chunks that will be produced. -Use `mapFn` to map each element of the new array to a chunk the length of `size`. +Use `Array.from()` to create a new array, that fits the number of chunks that will be produced. +Use `Array.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)); - // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] +// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` ### Compact diff --git a/snippets/chunk-array.md b/snippets/chunk-array.md index de6c5a568..c14bf269d 100644 --- a/snippets/chunk-array.md +++ b/snippets/chunk-array.md @@ -1,11 +1,11 @@ ### Chunk array -Use `Array.apply()` to create a new array, that fits the number of chunks that will be produced. -Use `Array.map()` to map each element of the new array to a chunk the length of `size`. +Use `Array.from()` to create a new array, that fits the number of chunks that will be produced. +Use `Array.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.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); + Array.from({length: Math.ceil(arr.length / size)}, (v, i) => arr.slice(i * size, i * size + size)); // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` From f8d55631c6a5d9e4790d30347b45d675c1b0e10c Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:10:47 +0200 Subject: [PATCH 126/202] Merge pull request #88 from darrenscerri/shuffle --- README.md | 7 +++---- snippets/randomize-order-of-array.md | 8 -------- snippets/shuffle-array-values.md | 12 ------------ snippets/shuffle-array.md | 8 ++++++++ 4 files changed, 11 insertions(+), 24 deletions(-) delete mode 100644 snippets/randomize-order-of-array.md delete mode 100644 snippets/shuffle-array-values.md create mode 100644 snippets/shuffle-array.md diff --git a/README.md b/README.md index dd66eebff..efc81a9de 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) * [Scroll to top](#scroll-to-top) -* [Shuffle array values](#shuffle-array-values) +* [Shuffle array](#shuffle-array) * [Similarity between arrays](#similarity-between-arrays) * [Sleep](#sleep) * [Sort characters in string (alphabetical)](#sort-characters-in-string-alphabetical) @@ -662,10 +662,9 @@ const scrollToTop = _ => { // scrollToTop() ``` -### Shuffle array values +### Shuffle array -Create an array of random values by using `Array.map()` and `Math.random()`. -Use `Array.sort()` to sort the elements of the original array based on the random values. +Use `Array.sort()` to reorder elements, using `Math.random()` in the comparator. ```js const shuffle = arr => { diff --git a/snippets/randomize-order-of-array.md b/snippets/randomize-order-of-array.md deleted file mode 100644 index 456a00607..000000000 --- a/snippets/randomize-order-of-array.md +++ /dev/null @@ -1,8 +0,0 @@ -### Randomize order of array - -Use `Array.sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. - -```js -const randomizeOrder = arr => arr.sort((a, b) => Math.random() >= 0.5 ? -1 : 1); -// randomizeOrder([1,2,3]) -> [1,3,2] -``` diff --git a/snippets/shuffle-array-values.md b/snippets/shuffle-array-values.md deleted file mode 100644 index ab3698a31..000000000 --- a/snippets/shuffle-array-values.md +++ /dev/null @@ -1,12 +0,0 @@ -### Shuffle array values - -Create an array of random values by using `Array.map()` and `Math.random()`. -Use `Array.sort()` to sort the elements of the original array based on the random values. - -```js -const shuffle = arr => { - let r = arr.map(Math.random); - return arr.sort((a, b) => r[a] - r[b]); -}; -// shuffle([1,2,3]) -> [2, 1, 3] -``` diff --git a/snippets/shuffle-array.md b/snippets/shuffle-array.md new file mode 100644 index 000000000..6266f9ecf --- /dev/null +++ b/snippets/shuffle-array.md @@ -0,0 +1,8 @@ +### Shuffle array + +Use `Array.sort()` to reorder elements, using `Math.random()` in the comparator. + +```js +const shuffle = arr => arr.sort(() => Math.random() - 0.5); +// shuffle([1,2,3]) -> [2,3,1] +``` From a528b7f7093c748d7cedf87d0338a9d850753bad Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:15:49 +0200 Subject: [PATCH 127/202] Build README --- README.md | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index efc81a9de..db026b6c2 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,6 @@ * [Promisify](#promisify) * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) -* [Randomize order of array](#randomize-order-of-array) * [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) @@ -597,15 +596,6 @@ const randomInRange = (min, max) => Math.random() * (max - min) + min; // randomInRange(2,10) -> 6.0211363285087005 ``` -### Randomize order of array - -Use `Array.sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. - -```js -const randomizeOrder = arr => arr.sort((a, b) => Math.random() >= 0.5 ? -1 : 1); -// randomizeOrder([1,2,3]) -> [1,3,2] -``` - ### Redirect to URL Use `window.location.href` or `window.location.replace()` to redirect to `url`. @@ -667,11 +657,8 @@ const scrollToTop = _ => { Use `Array.sort()` to reorder elements, using `Math.random()` in the comparator. ```js -const shuffle = arr => { - let r = arr.map(Math.random); - return arr.sort((a, b) => r[a] - r[b]); -}; -// shuffle([1,2,3]) -> [2, 1, 3] +const shuffle = arr => arr.sort(() => Math.random() - 0.5); +// shuffle([1,2,3]) -> [2,3,1] ``` ### Similarity between arrays From 66702ee4764080e9a355076b430603ff26168d56 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:23:21 +0200 Subject: [PATCH 128/202] Update validate-email.md --- snippets/validate-email.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/snippets/validate-email.md b/snippets/validate-email.md index 57a8afd2a..b4037d4aa 100644 --- a/snippets/validate-email.md +++ b/snippets/validate-email.md @@ -1,10 +1,11 @@ -### Validate Email +### Validate email - Regex is taken from https://stackoverflow.com/questions/46155/how-to-validate-email-address-in-javascript - Returns `true` if email is valid, `false` if not. +Use a regular experssion to check if the email is valid. +Returns `true` if email is valid, `false` if not. ```js - const validateEmail = str => /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(str); +const validateEmail = str => + /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(str); // isemail(mymail@gmail.com) -> true ``` From bede528c5265c304f14f0064030b310f40ac9536 Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 14 Dec 2017 20:24:07 +1100 Subject: [PATCH 129/202] Use explicit default value --- snippets/standard-deviation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/standard-deviation.md b/snippets/standard-deviation.md index 442052761..f07cb4f4c 100644 --- a/snippets/standard-deviation.md +++ b/snippets/standard-deviation.md @@ -6,7 +6,7 @@ of the values to determine the standard deviation of an array of numbers. Since there are two types of standard deviation, population and sample, you can use a flag to switch to population (sample is default). ```js -const standardDeviation = (arr, usePopulation) => { +const standardDeviation = (arr, usePopulation = false) => { const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; return Math.sqrt( arr.reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) From 3fa2d41ff33ec1a0e9f13b81c757356e0a9cc938 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:24:46 +0200 Subject: [PATCH 130/202] Build README --- README.md | 12 ++++++++++++ snippets/validate-email.md | 13 ++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index db026b6c2..befac0394 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ * [Unique values of array](#unique-values-of-array) * [URL parameters](#url-parameters) * [UUID generator](#uuid-generator) +* [Validate email](#validate-email) * [Validate number](#validate-number) * [Value or default](#value-or-default) @@ -768,6 +769,17 @@ const uuid = _ => // uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' ``` +### Validate email + +Use a regular experssion to check if the email is valid. +Returns `true` if email is valid, `false` if not. + +```js +const validateEmail = str => + /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(str); +// validateEmail(mymail@gmail.com) -> true +``` + ### Validate number Use `!isNaN` in combination with `parseFloat()` to check if the argument is a number. diff --git a/snippets/validate-email.md b/snippets/validate-email.md index b4037d4aa..d83a41904 100644 --- a/snippets/validate-email.md +++ b/snippets/validate-email.md @@ -1,11 +1,10 @@ ### Validate email - + Use a regular experssion to check if the email is valid. Returns `true` if email is valid, `false` if not. - - ```js -const validateEmail = str => + +```js +const validateEmail = str => /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(str); - // isemail(mymail@gmail.com) -> true - ``` - +// validateEmail(mymail@gmail.com) -> true +``` From 2c30c0afdefb9fc194bd0142d2734e24ec6dc689 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:29:20 +0200 Subject: [PATCH 131/202] Update standard-deviation.md --- snippets/standard-deviation.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/snippets/standard-deviation.md b/snippets/standard-deviation.md index f07cb4f4c..e559972bb 100644 --- a/snippets/standard-deviation.md +++ b/snippets/standard-deviation.md @@ -1,17 +1,15 @@ ### Standard deviation -Use `Array.reduce()` to calculate the mean of the values, the variance of the values, and the sum of the variance -of the values to determine the standard deviation of an array of numbers. - -Since there are two types of standard deviation, population and sample, you can use a flag to switch to population (sample is default). +Use `Array.reduce()` to calculate the mean, variance and the sum of the variance of the values, the variance of the values, then +determine the standard deviation. +You can omit the second argument to get the sample standard deviation or set it to `true` to get the population standard deviation. ```js const standardDeviation = (arr, usePopulation = false) => { const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; return Math.sqrt( arr.reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) - .reduce((acc, val) => acc + val, 0) - / (arr.length - (usePopulation ? 0 : 1)) + .reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1)) ); } // standardDeviation([10,2,38,23,38,23,21]) -> 13.284434142114991 (sample) From 0f775ba97b25ca1b3e3ec0d4c1b76b7569da2941 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:30:00 +0200 Subject: [PATCH 132/202] Build README --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index befac0394..d0393e21a 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ * [Similarity between arrays](#similarity-between-arrays) * [Sleep](#sleep) * [Sort characters in string (alphabetical)](#sort-characters-in-string-alphabetical) +* [Standard deviation](#standard-deviation) * [Sum of array of numbers](#sum-of-array-of-numbers) * [Swap values of two variables](#swap-values-of-two-variables) * [Tail of list](#tail-of-list) @@ -696,6 +697,24 @@ const sortCharactersInString = str => // sortCharactersInString('cabbage') -> 'aabbceg' ``` +### Standard deviation + +Use `Array.reduce()` to calculate the mean, variance and the sum of the variance of the values, the variance of the values, then +determine the standard deviation. +You can omit the second argument to get the sample standard deviation or set it to `true` to get the population standard deviation. + +```js +const standardDeviation = (arr, usePopulation = false) => { + const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; + return Math.sqrt( + arr.reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) + .reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1)) + ); + } +// standardDeviation([10,2,38,23,38,23,21]) -> 13.284434142114991 (sample) +// standardDeviation([10,2,38,23,38,23,21], true) -> 12.29899614287479 (population) +``` + ### Sum of array of numbers Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. From d9662f3953889b072c01492b984d337c7cfc9733 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:32:08 +0200 Subject: [PATCH 133/202] Update and rename check_for_boolean.md to check-for-boolean-primitive-values.md --- snippets/check-for-boolean-primitive-values.md | 8 ++++++++ snippets/check_for_boolean.md | 10 ---------- 2 files changed, 8 insertions(+), 10 deletions(-) create mode 100644 snippets/check-for-boolean-primitive-values.md delete mode 100644 snippets/check_for_boolean.md diff --git a/snippets/check-for-boolean-primitive-values.md b/snippets/check-for-boolean-primitive-values.md new file mode 100644 index 000000000..308e3a085 --- /dev/null +++ b/snippets/check-for-boolean-primitive-values.md @@ -0,0 +1,8 @@ +### Check for boolean primitive values + +Use `typeof` to check if a value is classified as a boolean primitive. + +```js +const isBool = val => typeof val === 'boolean'; +// isBool(null) -> false +``` diff --git a/snippets/check_for_boolean.md b/snippets/check_for_boolean.md deleted file mode 100644 index a96719aea..000000000 --- a/snippets/check_for_boolean.md +++ /dev/null @@ -1,10 +0,0 @@ -### Check for Boolean Primitive Values - -Check if a value is classified as a boolean primitive. Return true or false. - -function booWho(bool) { - return typeof bool === 'boolean'; -} - -// test here -booWho(null); From 8ca776aa03843deca3dfc5c6fd18f89259762b2f Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 04:35:14 -0500 Subject: [PATCH 134/202] ran npm run build-list & add take.md --- README.md | 14 +++++++++++++- snippets/take.md | 10 ++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 snippets/take.md diff --git a/README.md b/README.md index d0393e21a..3abae27c6 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * [Promisify](#promisify) * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -70,6 +70,7 @@ * [Sum of array of numbers](#sum-of-array-of-numbers) * [Swap values of two variables](#swap-values-of-two-variables) * [Tail of list](#tail-of-list) +* [Take](#take) * [Truncate a string](#truncate-a-string) * [Unique values of array](#unique-values-of-array) * [URL parameters](#url-parameters) @@ -743,6 +744,17 @@ const tail = arr => arr.length > 1 ? arr.slice(1) : arr; // tail([1]) -> [1] ``` +### Take + +Use `.slice()` to create a slice of the array with n elements taken from the beginning. + +```js +const take = (arr, n) => n === undefined ? arr.slice(0, 1) : arr.slice(0, n); + +// take([1, 2, 3], 5) -> [1, 2, 3] +// take([1, 2, 3], 0) -> [] +``` + ### Truncate a String Determine if the string's `length` is greater than `num`. diff --git a/snippets/take.md b/snippets/take.md new file mode 100644 index 000000000..1cc7e77fe --- /dev/null +++ b/snippets/take.md @@ -0,0 +1,10 @@ +### Take + +Use `.slice()` to create a slice of the array with n elements taken from the beginning. + +```js +const take = (arr, n) => n === undefined ? arr.slice(0, 1) : arr.slice(0, n); + +// take([1, 2, 3], 5) -> [1, 2, 3] +// take([1, 2, 3], 0) -> [] +``` From ce2cd00079868c5b27d3b47e2bc820c87194b12f Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:36:20 +0200 Subject: [PATCH 135/202] Update and rename drop_elements_in_array.md to drop-elements-in-array.md --- snippets/drop-elements-in-array.md | 12 ++++++++++++ snippets/drop_elements_in_array.md | 19 ------------------- 2 files changed, 12 insertions(+), 19 deletions(-) create mode 100644 snippets/drop-elements-in-array.md delete mode 100644 snippets/drop_elements_in_array.md diff --git a/snippets/drop-elements-in-array.md b/snippets/drop-elements-in-array.md new file mode 100644 index 000000000..0ad2ab5e9 --- /dev/null +++ b/snippets/drop-elements-in-array.md @@ -0,0 +1,12 @@ +### Drop elements in array + +Loop through the array, using `Array.shift()` to drop the first element of the array until the returned value from the function is `true`. +Returns the remaining elements. + +```js +const dropElements = (arr,func) => { + while(arr.length > 0 && !func(arr[0])) arr.shift(); + return arr; +} +// dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4] +``` diff --git a/snippets/drop_elements_in_array.md b/snippets/drop_elements_in_array.md deleted file mode 100644 index 73e2688b5..000000000 --- a/snippets/drop_elements_in_array.md +++ /dev/null @@ -1,19 +0,0 @@ -### Drop It - -Drop the elements of an array (first argument), starting from the front, until the predicate (second argument) returns true. - -Method - -- Use a while loop with Array.prototype.shift() to continue checking and dropping the first element of the array until the function returns true. It also makes sure the array is not empty first to avoid infinite loops. -- Return the filtered array. - -``` -function dropElements(arr, func) { - while(arr.length > 0 && !func(arr[0])) { - arr.shift(); - } - return arr; -} - -// test here -dropElements([1, 2, 3, 4], function(n) {return n >= 3;}); -``` From 236616efea4cbc88a0bde56b186addc4d19ce78b Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 04:46:16 -0500 Subject: [PATCH 136/202] refactor take --- README.md | 2 +- snippets/take.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3abae27c6..4a1ea0529 100644 --- a/README.md +++ b/README.md @@ -749,7 +749,7 @@ const tail = arr => arr.length > 1 ? arr.slice(1) : arr; Use `.slice()` to create a slice of the array with n elements taken from the beginning. ```js -const take = (arr, n) => n === undefined ? arr.slice(0, 1) : arr.slice(0, n); +const take = (arr, n = 1) => arr.slice(0, n); // take([1, 2, 3], 5) -> [1, 2, 3] // take([1, 2, 3], 0) -> [] diff --git a/snippets/take.md b/snippets/take.md index 1cc7e77fe..f597728ea 100644 --- a/snippets/take.md +++ b/snippets/take.md @@ -3,7 +3,7 @@ Use `.slice()` to create a slice of the array with n elements taken from the beginning. ```js -const take = (arr, n) => n === undefined ? arr.slice(0, 1) : arr.slice(0, n); +const take = (arr, n = 1) => arr.slice(0, n); // take([1, 2, 3], 5) -> [1, 2, 3] // take([1, 2, 3], 0) -> [] From db28e1ee28385d8946e09ebdcf6f30da1b0b7507 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:50:52 +0200 Subject: [PATCH 137/202] Update take.md --- snippets/take.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/take.md b/snippets/take.md index f597728ea..80142031d 100644 --- a/snippets/take.md +++ b/snippets/take.md @@ -1,6 +1,6 @@ ### Take -Use `.slice()` to create a slice of the array with n elements taken from the beginning. +Use `Array.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); From a93268e5969c77c38d9a587056581cb39f2b0835 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:51:24 +0200 Subject: [PATCH 138/202] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a1ea0529..0c9b72501 100644 --- a/README.md +++ b/README.md @@ -746,7 +746,7 @@ const tail = arr => arr.length > 1 ? arr.slice(1) : arr; ### Take -Use `.slice()` to create a slice of the array with n elements taken from the beginning. +Use `Array.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); From f7095814f4cfa4b4c278caa7dec3be7383c3ebc3 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:55:45 +0200 Subject: [PATCH 139/202] Build README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c9b72501..1015e7c72 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * [Promisify](#promisify) * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) From c52476eab4d574349d13ba54103b57dcba826131 Mon Sep 17 00:00:00 2001 From: sabareesh Date: Thu, 14 Dec 2017 15:39:17 +0530 Subject: [PATCH 140/202] array concat functionality added --- README.md | 12 +++++++++++- snippets/concat.md | 8 ++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 snippets/concat.md diff --git a/README.md b/README.md index a125ed5c6..77a5233e9 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ * [Check for palindrome](#check-for-palindrome) * [Chunk array](#chunk-array) * [Compact](#compact) +* [Concat](#concat) * [Count occurrences of a value in array](#count-occurrences-of-a-value-in-array) * [Current URL](#current-url) * [Curry](#curry) @@ -57,7 +58,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -206,6 +207,15 @@ const compact = (arr) => arr.filter(v => v); // compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] ``` +### Concat + +Creates a new array concatenating array with any additional arrays and/or values `args` using `Array.concat()`. + +```js +const ArrayConcat = (arr, ...args) => arr.concat(...args); +// ArrayConcat([1], [1, 2, 3, [4]]) -> [1, 2, 3, [4]] +``` + ### Count occurrences of a value in array Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. diff --git a/snippets/concat.md b/snippets/concat.md new file mode 100644 index 000000000..0f6c8bcb1 --- /dev/null +++ b/snippets/concat.md @@ -0,0 +1,8 @@ +### Concat + +Creates a new array concatenating array with any additional arrays and/or values `args` using `Array.concat()`. + +```js +const ArrayConcat = (arr, ...args) => arr.concat(...args); +// ArrayConcat([1], [1, 2, 3, [4]]) -> [1, 2, 3, [4]] +``` From 9ebbe62fb97a06d53df8014e196a2ef0e4d7f124 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 12:16:25 +0200 Subject: [PATCH 141/202] Update concat.md Improved description a little. --- snippets/concat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/concat.md b/snippets/concat.md index 0f6c8bcb1..677bc8871 100644 --- a/snippets/concat.md +++ b/snippets/concat.md @@ -1,6 +1,6 @@ ### Concat -Creates a new array concatenating array with any additional arrays and/or values `args` using `Array.concat()`. +Use `Array.concat()` to concatenate and array with any additional arrays and/or values, specified in `args`. ```js const ArrayConcat = (arr, ...args) => arr.concat(...args); From 67761753118ebf460a4a0fb1dcaa336c7abce129 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 12:17:11 +0200 Subject: [PATCH 142/202] Update and rename concat.md to array-concatenation.md --- snippets/{concat.md => array-concatenation.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename snippets/{concat.md => array-concatenation.md} (90%) diff --git a/snippets/concat.md b/snippets/array-concatenation.md similarity index 90% rename from snippets/concat.md rename to snippets/array-concatenation.md index 677bc8871..39d978d6e 100644 --- a/snippets/concat.md +++ b/snippets/array-concatenation.md @@ -1,4 +1,4 @@ -### Concat +### Array concatenation Use `Array.concat()` to concatenate and array with any additional arrays and/or values, specified in `args`. From b8b1994bfdd30b245fba2756630dd9b22fabf598 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 12:18:42 +0200 Subject: [PATCH 143/202] Build README --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 1015e7c72..a050fb089 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ ## Contents * [Anagrams of string (with duplicates)](#anagrams-of-string-with-duplicates) +* [Array concatenation](#array-concatenation) * [Array difference](#array-difference) * [Array intersection](#array-intersection) * [Array union](#array-union) @@ -95,6 +96,15 @@ const anagrams = str => { // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` +### Array concatenation + +Use `Array.concat()` to concatenate and array with any additional arrays and/or values, specified in `args`. + +```js +const ArrayConcat = (arr, ...args) => arr.concat(...args); +// ArrayConcat([1], [1, 2, 3, [4]]) -> [1, 2, 3, [4]] +``` + ### Array difference Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. From 9760ddf0ef32c3de74ab5dbf2a2189a0905dfbe4 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 12:29:51 +0200 Subject: [PATCH 144/202] Fixed arrayConcat example --- README.md | 4 ++-- snippets/array-concatenation.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a050fb089..ee3f560f7 100644 --- a/README.md +++ b/README.md @@ -101,8 +101,8 @@ const anagrams = str => { Use `Array.concat()` to concatenate and array with any additional arrays and/or values, specified in `args`. ```js -const ArrayConcat = (arr, ...args) => arr.concat(...args); -// ArrayConcat([1], [1, 2, 3, [4]]) -> [1, 2, 3, [4]] +const arrayConcat = (arr, ...args) => arr.concat(...args); +// arrayConcat([1], [1, 2, 3, [4]]) -> [1, 1, 2, 3, [4]] ``` ### Array difference diff --git a/snippets/array-concatenation.md b/snippets/array-concatenation.md index 39d978d6e..b7b26ea26 100644 --- a/snippets/array-concatenation.md +++ b/snippets/array-concatenation.md @@ -3,6 +3,6 @@ Use `Array.concat()` to concatenate and array with any additional arrays and/or values, specified in `args`. ```js -const ArrayConcat = (arr, ...args) => arr.concat(...args); -// ArrayConcat([1], [1, 2, 3, [4]]) -> [1, 2, 3, [4]] +const arrayConcat = (arr, ...args) => arr.concat(...args); +// arrayConcat([1], [1, 2, 3, [4]]) -> [1, 1, 2, 3, [4]] ``` From 0d3a58249c6fac28944b7e24577584a549e2328d Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 12:31:43 +0200 Subject: [PATCH 145/202] Update arrayConcat example --- README.md | 2 +- snippets/array-concatenation.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ee3f560f7..ed642cf3f 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ Use `Array.concat()` to concatenate and array with any additional arrays and/or ```js const arrayConcat = (arr, ...args) => arr.concat(...args); -// arrayConcat([1], [1, 2, 3, [4]]) -> [1, 1, 2, 3, [4]] +// arrayConcat([1], 2, [3], [[4]]) -> [1,2,3,[4]] ``` ### Array difference diff --git a/snippets/array-concatenation.md b/snippets/array-concatenation.md index b7b26ea26..b4e2fa205 100644 --- a/snippets/array-concatenation.md +++ b/snippets/array-concatenation.md @@ -4,5 +4,5 @@ Use `Array.concat()` to concatenate and array with any additional arrays and/or ```js const arrayConcat = (arr, ...args) => arr.concat(...args); -// arrayConcat([1], [1, 2, 3, [4]]) -> [1, 1, 2, 3, [4]] +// arrayConcat([1], 2, [3], [[4]]) -> [1,2,3,[4]] ``` From ec2a43cb3c2f40e878a99642b9eb10043bcb8e3b Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 14 Dec 2017 21:34:48 +1100 Subject: [PATCH 146/202] Create element-is-visible-in-viewport.md https://codepen.io/anon/pen/MrwYzx Adjust the `transform: translate()` to test it out --- snippets/element-is-visible-in-viewport.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 snippets/element-is-visible-in-viewport.md diff --git a/snippets/element-is-visible-in-viewport.md b/snippets/element-is-visible-in-viewport.md new file mode 100644 index 000000000..68a690d0d --- /dev/null +++ b/snippets/element-is-visible-in-viewport.md @@ -0,0 +1,19 @@ +### Element is visible in viewport + +Use `Element.getBoundingClientRect()` and the `window.inner(Width|Height)` values +to determine if a given element is visible in the viewport. +Omit the second argument to determine if the element is entirely visible, or specify `true` to determine if +it is partially visible. + +```js +const elementIsVisibleInViewport = (el, partiallyVisible = false) => { + const { top, left, bottom, right } = el.getBoundingClientRect(); + return partiallyVisible + ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && + ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) + : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; +} +// e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10} +// elementIsInViewport(el) -> false (not fully visible) +// elementIsInViewport(el, true) -> true (partially visible) +``` From 6abffae5c489f8ca9f5535c7a21f51329e381836 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 12:50:15 +0200 Subject: [PATCH 147/202] Build README --- README.md | 24 ++++++++++++++++++++++++ snippets/join_array_like_objects.md | 11 ----------- 2 files changed, 24 insertions(+), 11 deletions(-) delete mode 100644 snippets/join_array_like_objects.md diff --git a/README.md b/README.md index ed642cf3f..6a9476c6f 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ * [Capitalize first letter of every word](#capitalize-first-letter-of-every-word) * [Capitalize first letter](#capitalize-first-letter) * [Chain asynchronous functions](#chain-asynchronous-functions) +* [Check for boolean primitive values](#check-for-boolean-primitive-values) * [Check for palindrome](#check-for-palindrome) * [Chunk array](#chunk-array) * [Compact](#compact) @@ -28,6 +29,7 @@ * [Deep flatten array](#deep-flatten-array) * [Distance between two points](#distance-between-two-points) * [Divisible by number](#divisible-by-number) +* [Drop elements in array](#drop-elements-in-array) * [Escape regular expression](#escape-regular-expression) * [Even or odd number](#even-or-odd-number) * [Factorial](#factorial) @@ -186,6 +188,15 @@ chainAsync([ */ ``` +### Check for boolean primitive values + +Use `typeof` to check if a value is classified as a boolean primitive. + +```js +const isBool = val => typeof val === 'boolean'; +// isBool(null) -> false +``` + ### Check for palindrome Convert string `toLowerCase()` and use `replace()` to remove non-alphanumeric characters from it. @@ -286,6 +297,19 @@ const isDivisible = (dividend, divisor) => dividend % divisor === 0; // isDivisible(6,3) -> true ``` +### Drop elements in array + +Loop through the array, using `Array.shift()` to drop the first element of the array until the returned value from the function is `true`. +Returns the remaining elements. + +```js +const dropElements = (arr,func) => { + while(arr.length > 0 && !func(arr[0])) arr.shift(); + return arr; +} +// dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4] +``` + ### Escape regular expression Use `replace()` to escape special characters. diff --git a/snippets/join_array_like_objects.md b/snippets/join_array_like_objects.md deleted file mode 100644 index 57acd6731..000000000 --- a/snippets/join_array_like_objects.md +++ /dev/null @@ -1,11 +0,0 @@ -### Joining an array-like object - -The following example joins array-like object (arguments), by calling Function.prototype.call on Array.prototype.join. - -``` -function f(a, b, c) { - var s = Array.prototype.join.call(arguments); - console.log(s); // '1,a,true' -} -f(1, 'a', true); -``` From 3aa0c5eec082f40a7665f7058a6d29abb38352b5 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 12:56:02 +0200 Subject: [PATCH 148/202] Added isX functions --- README.md | 65 ++++++++++++++++--- .../check-for-boolean-primitive-values.md | 8 --- snippets/is-boolean.md | 9 +++ snippets/is-function.md | 9 +++ snippets/is-number.md | 9 +++ snippets/is-string.md | 9 +++ snippets/is-symbol.md | 9 +++ 7 files changed, 100 insertions(+), 18 deletions(-) delete mode 100644 snippets/check-for-boolean-primitive-values.md create mode 100644 snippets/is-boolean.md create mode 100644 snippets/is-function.md create mode 100644 snippets/is-number.md create mode 100644 snippets/is-string.md create mode 100644 snippets/is-symbol.md diff --git a/README.md b/README.md index 6a9476c6f..822750209 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,6 @@ * [Capitalize first letter of every word](#capitalize-first-letter-of-every-word) * [Capitalize first letter](#capitalize-first-letter) * [Chain asynchronous functions](#chain-asynchronous-functions) -* [Check for boolean primitive values](#check-for-boolean-primitive-values) * [Check for palindrome](#check-for-palindrome) * [Chunk array](#chunk-array) * [Compact](#compact) @@ -47,6 +46,11 @@ * [Initial of list](#initial-of-list) * [Initialize array with range](#initialize-array-with-range) * [Initialize array with values](#initialize-array-with-values) +* [Is boolean](#is-boolean) +* [Is function](#is-function) +* [Is number](#is-number) +* [Is string](#is-string) +* [Is symbol](#is-symbol) * [Last of list](#last-of-list) * [Measure time taken by function](#measure-time-taken-by-function) * [Median of array of numbers](#median-of-array-of-numbers) @@ -188,15 +192,6 @@ chainAsync([ */ ``` -### Check for boolean primitive values - -Use `typeof` to check if a value is classified as a boolean primitive. - -```js -const isBool = val => typeof val === 'boolean'; -// isBool(null) -> false -``` - ### Check for palindrome Convert string `toLowerCase()` and use `replace()` to remove non-alphanumeric characters from it. @@ -485,6 +480,56 @@ const initializeArray = (n, value = 0) => Array(n).fill(value); // initializeArray(5, 2) -> [2,2,2,2,2] ``` +### Is boolean + +Use `typeof` to check if a value is classified as a boolean primitive. + +```js +const isBoolean = val => typeof val === 'boolean'; +// isBoolean(null) -> false +// isBoolean(false) -> true +``` + +### Is boolean + +Use `typeof` to check if a value is classified as a function primitive. + +```js +const isFunction = val => val && typeof val === 'function'; +// isFunction('x') -> false +// isFunction(x => x) -> true +``` + +### Is number + +Use `typeof` to check if a value is classified as a number primitive. + +```js +const isNumber = val => typeof val === 'number'; +// isNumber('1') -> false +// isNumber(1) -> true +``` + +### Is string + +Use `typeof` to check if a value is classified as a string primitive. + +```js +const isString = val => typeof val === 'string'; +// isString(10) -> false +// isString('10') -> true +``` + +### Is symbol + +Use `typeof` to check if a value is classified as a symbol primitive. + +```js +const isSymbol = val => typeof val === 'symbol'; +// isSymbol('x') -> false +// isSymbol(Symbol('x')) -> true +``` + ### Last of list Use `arr.slice(-1)[0]` to get the last element of the given array. diff --git a/snippets/check-for-boolean-primitive-values.md b/snippets/check-for-boolean-primitive-values.md deleted file mode 100644 index 308e3a085..000000000 --- a/snippets/check-for-boolean-primitive-values.md +++ /dev/null @@ -1,8 +0,0 @@ -### Check for boolean primitive values - -Use `typeof` to check if a value is classified as a boolean primitive. - -```js -const isBool = val => typeof val === 'boolean'; -// isBool(null) -> false -``` diff --git a/snippets/is-boolean.md b/snippets/is-boolean.md new file mode 100644 index 000000000..8625add35 --- /dev/null +++ b/snippets/is-boolean.md @@ -0,0 +1,9 @@ +### Is boolean + +Use `typeof` to check if a value is classified as a boolean primitive. + +```js +const isBoolean = val => typeof val === 'boolean'; +// isBoolean(null) -> false +// isBoolean(false) -> true +``` diff --git a/snippets/is-function.md b/snippets/is-function.md new file mode 100644 index 000000000..a406ee543 --- /dev/null +++ b/snippets/is-function.md @@ -0,0 +1,9 @@ +### Is boolean + +Use `typeof` to check if a value is classified as a function primitive. + +```js +const isFunction = val => val && typeof val === 'function'; +// isFunction('x') -> false +// isFunction(x => x) -> true +``` diff --git a/snippets/is-number.md b/snippets/is-number.md new file mode 100644 index 000000000..a647b39ed --- /dev/null +++ b/snippets/is-number.md @@ -0,0 +1,9 @@ +### Is number + +Use `typeof` to check if a value is classified as a number primitive. + +```js +const isNumber = val => typeof val === 'number'; +// isNumber('1') -> false +// isNumber(1) -> true +``` diff --git a/snippets/is-string.md b/snippets/is-string.md new file mode 100644 index 000000000..6721c59c6 --- /dev/null +++ b/snippets/is-string.md @@ -0,0 +1,9 @@ +### Is string + +Use `typeof` to check if a value is classified as a string primitive. + +```js +const isString = val => typeof val === 'string'; +// isString(10) -> false +// isString('10') -> true +``` diff --git a/snippets/is-symbol.md b/snippets/is-symbol.md new file mode 100644 index 000000000..53d4ce67c --- /dev/null +++ b/snippets/is-symbol.md @@ -0,0 +1,9 @@ +### Is symbol + +Use `typeof` to check if a value is classified as a symbol primitive. + +```js +const isSymbol = val => typeof val === 'symbol'; +// isSymbol('x') -> false +// isSymbol(Symbol('x')) -> true +``` From e6d89428f27dc8de158aa0407bb44c8a357df08b Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 13:04:09 +0200 Subject: [PATCH 149/202] Build README --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 822750209..1ff40dc0d 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ * [Distance between two points](#distance-between-two-points) * [Divisible by number](#divisible-by-number) * [Drop elements in array](#drop-elements-in-array) +* [Element is visible in viewport](#element-is-visible-in-viewport) * [Escape regular expression](#escape-regular-expression) * [Even or odd number](#even-or-odd-number) * [Factorial](#factorial) @@ -305,6 +306,26 @@ const dropElements = (arr,func) => { // dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4] ``` +### Element is visible in viewport + +Use `Element.getBoundingClientRect()` and the `window.inner(Width|Height)` values +to determine if a given element is visible in the viewport. +Omit the second argument to determine if the element is entirely visible, or specify `true` to determine if +it is partially visible. + +```js +const elementIsVisibleInViewport = (el, partiallyVisible = false) => { + const { top, left, bottom, right } = el.getBoundingClientRect(); + return partiallyVisible + ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && + ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) + : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; +} +// e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10} +// elementIsInViewport(el) -> false (not fully visible) +// elementIsInViewport(el, true) -> true (partially visible) +``` + ### Escape regular expression Use `replace()` to escape special characters. From 2e2513a81e881d0b37e7b2f53c4916b6fc662d34 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 13:05:13 +0200 Subject: [PATCH 150/202] Additional guidelines in CONTRIBUTING --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 09e28829b..db1670488 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,6 +45,8 @@ Here's what you can do to help: - Try to give meaningful names to variables. For example use `letter`, instead of `lt`. Some exceptions by convention are: - `arr` for arrays (usually as the snippet function's argument). - `str` for strings. + - `n` for a numeric value (usually as the snippet function's argument). + - `el` for DOM elements (usually as the snippet function's argument). - `val` or `v` for value (usually when iterating a list, mapping, sorting etc.). - `acc` for accumulators in `Array.reduce()`. - `(a,b)` for the two values compared when using `Array.sort()`. From 5520985d732318263e689efbf6f16af6c6269e6c Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 13:07:19 +0200 Subject: [PATCH 151/202] Updated builder with links to top --- README.md | 79 +++++++++++++++++++++++++++++++++++- scripts/builder.js | 2 +- static-parts/README-start.md | 2 +- 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1ff40dc0d..7e3df18b7 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ - 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. -## Contents +## Table of Contents * [Anagrams of string (with duplicates)](#anagrams-of-string-with-duplicates) * [Array concatenation](#array-concatenation) @@ -103,6 +103,7 @@ const anagrams = str => { // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` +[⬆ back to top](#table-of-contents) ### Array concatenation Use `Array.concat()` to concatenate and array with any additional arrays and/or values, specified in `args`. @@ -112,6 +113,7 @@ const arrayConcat = (arr, ...args) => arr.concat(...args); // arrayConcat([1], 2, [3], [[4]]) -> [1,2,3,[4]] ``` +[⬆ back to top](#table-of-contents) ### Array difference Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. @@ -121,6 +123,7 @@ const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has // difference([1,2,3], [1,2]) -> [3] ``` +[⬆ back to top](#table-of-contents) ### Array intersection Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. @@ -130,6 +133,7 @@ const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.ha // intersection([1,2,3], [4,3,2]) -> [2,3] ``` +[⬆ back to top](#table-of-contents) ### Array union Create a `Set` with all values of `a` and `b` and convert to an array. @@ -139,6 +143,7 @@ const union = (a, b) => Array.from(new Set([...a, ...b])) // union([1,2,3], [4,3,2]) -> [1,2,3,4] ``` +[⬆ back to top](#table-of-contents) ### Average of array of numbers Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. @@ -148,6 +153,7 @@ const average = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length; // average([1,2,3]) -> 2 ``` +[⬆ back to top](#table-of-contents) ### Bottom visible Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible. @@ -158,6 +164,7 @@ const bottomVisible = _ => // bottomVisible() -> true ``` +[⬆ back to top](#table-of-contents) ### Capitalize first letter of every word Use `replace()` to match the first character of each word and `toUpperCase()` to capitalize it. @@ -167,6 +174,7 @@ const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperC // capitalizeEveryWord('hello world!') -> 'Hello World!' ``` +[⬆ back to top](#table-of-contents) ### Capitalize first letter Use `slice(0,1)` and `toUpperCase()` to capitalize first letter, `slice(1)` to get the rest of the string. @@ -178,6 +186,7 @@ const capitalize = (str, lowerRest = false) => // capitalize('myName', true) -> 'Myname' ``` +[⬆ back to top](#table-of-contents) ### Chain asynchronous functions Loop through an array of functions containing asynchronous events, calling `next` when each asynchronous event has completed. @@ -193,6 +202,7 @@ chainAsync([ */ ``` +[⬆ back to top](#table-of-contents) ### Check for palindrome Convert string `toLowerCase()` and use `replace()` to remove non-alphanumeric characters from it. @@ -206,6 +216,7 @@ const palindrome = str => { // palindrome('taco cat') -> true ``` +[⬆ back to top](#table-of-contents) ### Chunk array Use `Array.from()` to create a new array, that fits the number of chunks that will be produced. @@ -218,6 +229,7 @@ const chunk = (arr, size) => // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` +[⬆ back to top](#table-of-contents) ### Compact Use `Array.filter()` to filter out falsey values (`false`, `null`, `0`, `""`, `undefined`, and `NaN`). @@ -227,6 +239,7 @@ const compact = (arr) => arr.filter(v => v); // compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] ``` +[⬆ back to top](#table-of-contents) ### Count occurrences of a value in array Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. @@ -236,6 +249,7 @@ const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + // countOccurrences([1,1,2,1,2,3], 1) -> 3 ``` +[⬆ back to top](#table-of-contents) ### Current URL Use `window.location.href` to get current URL. @@ -245,6 +259,7 @@ const currentUrl = _ => window.location.href; // currentUrl() -> 'https://google.com' ``` +[⬆ back to top](#table-of-contents) ### Curry Use recursion. @@ -264,6 +279,7 @@ const curry = (f, arity = f.length, next) => // curry(Math.min, 3)(10)(50)(2) -> 2 ``` +[⬆ back to top](#table-of-contents) ### Deep flatten array Use recursion. @@ -275,6 +291,7 @@ const deepFlatten = arr => // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] ``` +[⬆ back to top](#table-of-contents) ### Distance between two points Use `Math.hypot()` to calculate the Euclidean distance between two points. @@ -284,6 +301,7 @@ const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); // distance(1,1, 2,3) -> 2.23606797749979 ``` +[⬆ back to top](#table-of-contents) ### Divisible by number Use the modulo operator (`%`) to check if the remainder is equal to `0`. @@ -293,6 +311,7 @@ const isDivisible = (dividend, divisor) => dividend % divisor === 0; // isDivisible(6,3) -> true ``` +[⬆ back to top](#table-of-contents) ### Drop elements in array Loop through the array, using `Array.shift()` to drop the first element of the array until the returned value from the function is `true`. @@ -306,6 +325,7 @@ const dropElements = (arr,func) => { // dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4] ``` +[⬆ back to top](#table-of-contents) ### Element is visible in viewport Use `Element.getBoundingClientRect()` and the `window.inner(Width|Height)` values @@ -326,6 +346,7 @@ const elementIsVisibleInViewport = (el, partiallyVisible = false) => { // elementIsInViewport(el, true) -> true (partially visible) ``` +[⬆ back to top](#table-of-contents) ### Escape regular expression Use `replace()` to escape special characters. @@ -335,6 +356,7 @@ const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // escapeRegExp('(test)') -> \\(test\\) ``` +[⬆ back to top](#table-of-contents) ### Even or odd number Checks whether a number is odd or even using the modulo (`%`) operator. @@ -345,6 +367,7 @@ const isEven = num => num % 2 === 0; // isEven(3) -> false ``` +[⬆ back to top](#table-of-contents) ### Factorial Use recursion. @@ -356,6 +379,7 @@ const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); // factorial(6) -> 720 ``` +[⬆ back to top](#table-of-contents) ### Fibonacci array generator Create an empty array of the specific length, initializing the first two values (`0` and `1`). @@ -367,6 +391,7 @@ const fibonacci = n => // fibonacci(5) -> [0,1,1,2,3] ``` +[⬆ back to top](#table-of-contents) ### Filter out non-unique values in an array Use `Array.filter()` for an array containing only the unique values. @@ -376,6 +401,7 @@ const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexO // filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] ``` +[⬆ back to top](#table-of-contents) ### Flatten array Use `Array.reduce()` to get all elements inside the array and `concat()` to flatten them. @@ -385,6 +411,7 @@ const flatten = arr => arr.reduce((a, v) => a.concat(v), []); // flatten([1,[2],3,4]) -> [1,2,3,4] ``` +[⬆ back to top](#table-of-contents) ### Get max value from array Use `Math.max()` combined with the spread operator (`...`) to get the maximum value in the array. @@ -394,6 +421,7 @@ const arrayMax = arr => Math.max(...arr); // arrayMax([10, 1, 5]) -> 10 ``` +[⬆ back to top](#table-of-contents) ### Get min value from array Use `Math.min()` combined with the spread operator (`...`) to get the minimum value in the array. @@ -403,6 +431,7 @@ const arrayMin = arr => Math.min(...arr); // arrayMin([10, 1, 5]) -> 1 ``` +[⬆ back to top](#table-of-contents) ### Get native type of value Returns lower-cased constructor name of value, "undefined" or "null" if value is undefined or null @@ -413,6 +442,7 @@ const getType = v => // getType(new Set([1,2,3])) -> "set" ``` +[⬆ back to top](#table-of-contents) ### Get scroll position Use `pageXOffset` and `pageYOffset` if they are defined, otherwise `scrollLeft` and `scrollTop`. @@ -425,6 +455,7 @@ const getScrollPos = (el = window) => // getScrollPos() -> {x: 0, y: 200} ``` +[⬆ back to top](#table-of-contents) ### Greatest common divisor (GCD) Use recursion. @@ -436,6 +467,7 @@ const gcd = (x, y) => !y ? x : gcd(y, x % y); // gcd (8, 36) -> 4 ``` +[⬆ back to top](#table-of-contents) ### Group by Use `Array.map()` to map the values of an array to a function or property name. @@ -451,6 +483,7 @@ const groupBy = (arr, func) => // groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} ``` +[⬆ back to top](#table-of-contents) ### Hamming distance Use XOR operator (`^`) to find the bit difference between the two numbers, convert to binary string using `toString(2)`. @@ -462,6 +495,7 @@ const hammingDistance = (num1, num2) => // hammingDistance(2,3) -> 1 ``` +[⬆ back to top](#table-of-contents) ### Head of list Use `arr[0]` to return the first element of the passed array. @@ -471,6 +505,7 @@ const head = arr => arr[0]; // head([1,2,3]) -> 1 ``` +[⬆ back to top](#table-of-contents) ### Initial of list Use `arr.slice(0,-1)`to return all but the last element of the array. @@ -480,6 +515,7 @@ const initial = arr => arr.slice(0, -1); // initial([1,2,3]) -> [1,2] ``` +[⬆ back to top](#table-of-contents) ### Initialize array with range Use `Array(end-start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. @@ -491,6 +527,7 @@ const initializeArrayRange = (end, start = 0) => // initializeArrayRange(5) -> [0,1,2,3,4] ``` +[⬆ back to top](#table-of-contents) ### Initialize array with values Use `Array(n)` to create an array of the desired length, `fill(v)` to fill it with the desired values. @@ -501,6 +538,7 @@ const initializeArray = (n, value = 0) => Array(n).fill(value); // initializeArray(5, 2) -> [2,2,2,2,2] ``` +[⬆ back to top](#table-of-contents) ### Is boolean Use `typeof` to check if a value is classified as a boolean primitive. @@ -511,6 +549,7 @@ const isBoolean = val => typeof val === 'boolean'; // isBoolean(false) -> true ``` +[⬆ back to top](#table-of-contents) ### Is boolean Use `typeof` to check if a value is classified as a function primitive. @@ -521,6 +560,7 @@ const isFunction = val => val && typeof val === 'function'; // isFunction(x => x) -> true ``` +[⬆ back to top](#table-of-contents) ### Is number Use `typeof` to check if a value is classified as a number primitive. @@ -531,6 +571,7 @@ const isNumber = val => typeof val === 'number'; // isNumber(1) -> true ``` +[⬆ back to top](#table-of-contents) ### Is string Use `typeof` to check if a value is classified as a string primitive. @@ -541,6 +582,7 @@ const isString = val => typeof val === 'string'; // isString('10') -> true ``` +[⬆ back to top](#table-of-contents) ### Is symbol Use `typeof` to check if a value is classified as a symbol primitive. @@ -551,6 +593,7 @@ const isSymbol = val => typeof val === 'symbol'; // isSymbol(Symbol('x')) -> true ``` +[⬆ back to top](#table-of-contents) ### Last of list Use `arr.slice(-1)[0]` to get the last element of the given array. @@ -560,6 +603,7 @@ const last = arr => arr.slice(-1)[0]; // last([1,2,3]) -> 3 ``` +[⬆ back to top](#table-of-contents) ### Measure time taken by function Use `performance.now()` to get start and end time for the function, `console.log()` the time taken. @@ -574,6 +618,7 @@ const timeTaken = callback => { // timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) ``` +[⬆ back to top](#table-of-contents) ### Median of array of numbers Find the middle of the array, use `Array.sort()` to sort the values. @@ -588,6 +633,7 @@ const median = arr => { // median([0,10,-2,7]) -> 3.5 ``` +[⬆ back to top](#table-of-contents) ### Object from key-value pairs Use `Array.reduce()` to create and combine key-value pairs. @@ -597,6 +643,7 @@ const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); // objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} ``` +[⬆ back to top](#table-of-contents) ### Object to key-value pairs Use `Object.keys()` and `Array.map()` to iterate over the object's keys and produce an array with key-value pairs. @@ -606,6 +653,7 @@ const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); // objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) ``` +[⬆ back to top](#table-of-contents) ### Ordinal suffix of number Use the modulo operator (`%`) to find values of single and tens digits. @@ -622,6 +670,7 @@ const toOrdinalSuffix = num => { // toOrdinalSuffix("123") -> "123rd" ``` +[⬆ back to top](#table-of-contents) ### Percentile Use `Array.reduce()` to calculate how many numbers are below the value and how many are the same value and @@ -633,6 +682,7 @@ const percentile = (arr, val) => // percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 ``` +[⬆ back to top](#table-of-contents) ### Pick Use `Array.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. @@ -644,6 +694,7 @@ const pick = (obj, arr) => // pick(object, ['a', 'c'])['a'] -> 1 ``` +[⬆ back to top](#table-of-contents) ### Pipe Use `Array.reduce()` to pass value through functions. @@ -653,6 +704,7 @@ const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg); // pipe(btoa, x => x.toUpperCase())("Test") -> "VGVZDA==" ``` +[⬆ back to top](#table-of-contents) ### Powerset Use `Array.reduce()` combined with `Array.map()` to iterate over elements and combine into an array containing all combinations. @@ -663,6 +715,7 @@ const powerset = arr => // powerset([1,2]) -> [[], [1], [2], [2,1]] ``` +[⬆ back to top](#table-of-contents) ### Promisify Use currying to return a function returning a `Promise` that calls the original function. @@ -681,6 +734,7 @@ const promisify = func => // delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s ``` +[⬆ back to top](#table-of-contents) ### Random integer in range Use `Math.random()` to generate a random number and map it to the desired range, using `Math.floor()` to make it an integer. @@ -690,6 +744,7 @@ const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min // randomIntegerInRange(0, 5) -> 2 ``` +[⬆ back to top](#table-of-contents) ### Random number in range Use `Math.random()` to generate a random value, map it to the desired range using multiplication. @@ -699,6 +754,7 @@ const randomInRange = (min, max) => Math.random() * (max - min) + min; // randomInRange(2,10) -> 6.0211363285087005 ``` +[⬆ back to top](#table-of-contents) ### Redirect to URL Use `window.location.href` or `window.location.replace()` to redirect to `url`. @@ -710,6 +766,7 @@ const redirect = (url, asLink = true) => // redirect('https://google.com') ``` +[⬆ back to top](#table-of-contents) ### Reverse a string Use array destructuring and `Array.reverse()` to reverse the order of the characters in the string. @@ -720,6 +777,7 @@ const reverseString = str => [...str].reverse().join(''); // reverseString('foobar') -> 'raboof' ``` +[⬆ back to top](#table-of-contents) ### RGB to hexadecimal Convert given RGB parameters to hexadecimal string using bitwise left-shift operator (`<<`) and `toString(16)`, then `padStart(6,'0')` to get a 6-digit hexadecimal value. @@ -729,6 +787,7 @@ const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6 // rgbToHex(255, 165, 1) -> 'ffa501' ``` +[⬆ back to top](#table-of-contents) ### Run promises in series Run an array of promises in series using `Array.reduce()` by creating a promise chain, where each promise returns the next promise when resolved. @@ -739,6 +798,7 @@ const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); // series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete ``` +[⬆ back to top](#table-of-contents) ### Scroll to top Get distance from top using `document.documentElement.scrollTop` or `document.body.scrollTop`. @@ -755,6 +815,7 @@ const scrollToTop = _ => { // scrollToTop() ``` +[⬆ back to top](#table-of-contents) ### Shuffle array Use `Array.sort()` to reorder elements, using `Math.random()` in the comparator. @@ -764,6 +825,7 @@ const shuffle = arr => arr.sort(() => Math.random() - 0.5); // shuffle([1,2,3]) -> [2,3,1] ``` +[⬆ back to top](#table-of-contents) ### Similarity between arrays Use `filter()` to remove values that are not part of `values`, determined using `includes()`. @@ -773,6 +835,7 @@ const similarity = (arr, values) => arr.filter(v => values.includes(v)); // similarity([1,2,3], [1,2,4]) -> [1,2] ``` +[⬆ back to top](#table-of-contents) ### Sleep Delay executing part of an `async` function, by putting it to sleep, returning a `Promise`. @@ -788,6 +851,7 @@ async function sleepyWork() { */ ``` +[⬆ back to top](#table-of-contents) ### Sort characters in string (alphabetical) Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, recombine using `join('')`. @@ -798,6 +862,7 @@ const sortCharactersInString = str => // sortCharactersInString('cabbage') -> 'aabbceg' ``` +[⬆ back to top](#table-of-contents) ### Standard deviation Use `Array.reduce()` to calculate the mean, variance and the sum of the variance of the values, the variance of the values, then @@ -816,6 +881,7 @@ const standardDeviation = (arr, usePopulation = false) => { // standardDeviation([10,2,38,23,38,23,21], true) -> 12.29899614287479 (population) ``` +[⬆ back to top](#table-of-contents) ### Sum of array of numbers Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. @@ -825,6 +891,7 @@ const sum = arr => arr.reduce((acc, val) => acc + val, 0); // sum([1,2,3,4]) -> 10 ``` +[⬆ back to top](#table-of-contents) ### Swap values of two variables Use array destructuring to swap values between two variables. @@ -834,6 +901,7 @@ Use array destructuring to swap values between two variables. // [x, y] = [y, x] ``` +[⬆ back to top](#table-of-contents) ### Tail of list Return `arr.slice(1)` if the array's `length` is more than `1`, otherwise return the whole array. @@ -844,6 +912,7 @@ const tail = arr => arr.length > 1 ? arr.slice(1) : arr; // tail([1]) -> [1] ``` +[⬆ back to top](#table-of-contents) ### Take Use `Array.slice()` to create a slice of the array with `n` elements taken from the beginning. @@ -855,6 +924,7 @@ const take = (arr, n = 1) => arr.slice(0, n); // take([1, 2, 3], 0) -> [] ``` +[⬆ back to top](#table-of-contents) ### Truncate a String Determine if the string's `length` is greater than `num`. @@ -866,6 +936,7 @@ const truncate = (str, num) => // truncate('boomerang', 7) -> 'boom...' ``` +[⬆ back to top](#table-of-contents) ### Unique values of array Use ES6 `Set` and the `...rest` operator to discard all duplicated values. @@ -875,6 +946,7 @@ const unique = arr => [...new Set(arr)]; // unique([1,2,2,3,4,4,5]) -> [1,2,3,4,5] ``` +[⬆ back to top](#table-of-contents) ### URL parameters Use `match()` with an appropriate regular expression to get all key-value pairs, `Array.reduce()` to map and combine them into a single object. @@ -888,6 +960,7 @@ const getUrlParameters = url => // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} ``` +[⬆ back to top](#table-of-contents) ### UUID generator Use `crypto` API to generate a UUID, compliant with [RFC4122](https://www.ietf.org/rfc/rfc4122.txt) version 4. @@ -900,6 +973,7 @@ const uuid = _ => // uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' ``` +[⬆ back to top](#table-of-contents) ### Validate email Use a regular experssion to check if the email is valid. @@ -911,6 +985,7 @@ const validateEmail = str => // validateEmail(mymail@gmail.com) -> true ``` +[⬆ back to top](#table-of-contents) ### Validate number Use `!isNaN` in combination with `parseFloat()` to check if the argument is a number. @@ -922,6 +997,7 @@ const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == // validateNumber('10') -> true ``` +[⬆ back to top](#table-of-contents) ### Value or default Returns value, or default value if passed value is `falsy`. @@ -931,6 +1007,7 @@ const valueOrDefault = (value, d) => value || d; // valueOrDefault(NaN, 30) -> 30 ``` +[⬆ back to top](#table-of-contents) ## Credits *Icons made by [Smashicons](https://www.flaticon.com/authors/smashicons) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/).* diff --git a/scripts/builder.js b/scripts/builder.js index b9a5d5bc8..220469705 100644 --- a/scripts/builder.js +++ b/scripts/builder.js @@ -45,7 +45,7 @@ try { output += `* [${snippet[0][0].toUpperCase() + snippet[0].replace(/-/g,' ').slice(1,snippet[0].length-3)}](#${snippet[0].slice(0,snippet[0].length-3).replace(/\(/g,'').replace(/\)/g,'').toLowerCase()})\n` output += '\n'; for(var snippet of Object.entries(snippets)) - output += `${snippet[1]+'\n'}`; + output += `${snippet[1]+'\n[⬆ back to top](#table-of-contents)\n'}`; output += `${endPart+'\n'}`; fs.writeFileSync('README.md', output); } diff --git a/static-parts/README-start.md b/static-parts/README-start.md index 1bfdbba0e..6a6504483 100644 --- a/static-parts/README-start.md +++ b/static-parts/README-start.md @@ -7,4 +7,4 @@ - 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. -## Contents +## Table of Contents From 4c6182775d1012427485aa6036535375033e3433 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 13:10:06 +0200 Subject: [PATCH 152/202] Add isArray --- README.md | 12 ++++++++++++ snippets/is-array.md | 9 +++++++++ 2 files changed, 21 insertions(+) create mode 100644 snippets/is-array.md diff --git a/README.md b/README.md index 7e3df18b7..b838a8f6c 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ * [Initial of list](#initial-of-list) * [Initialize array with range](#initialize-array-with-range) * [Initialize array with values](#initialize-array-with-values) +* [Is array](#is-array) * [Is boolean](#is-boolean) * [Is function](#is-function) * [Is number](#is-number) @@ -538,6 +539,17 @@ const initializeArray = (n, value = 0) => Array(n).fill(value); // initializeArray(5, 2) -> [2,2,2,2,2] ``` +[⬆ back to top](#table-of-contents) +### Is array + +Use `Array.isArray()` to check if a value is classified as an array. + +```js +const isArray = val => val && Array.isArray(val); +// isArray(null) -> false +// isArray([1]) -> true +``` + [⬆ back to top](#table-of-contents) ### Is boolean diff --git a/snippets/is-array.md b/snippets/is-array.md new file mode 100644 index 000000000..7652f74c9 --- /dev/null +++ b/snippets/is-array.md @@ -0,0 +1,9 @@ +### Is array + +Use `Array.isArray()` to check if a value is classified as an array. + +```js +const isArray = val => val && Array.isArray(val); +// isArray(null) -> false +// isArray([1]) -> true +``` From ba63cbfcd22d028b824e3b3e1a83615c247c430f Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 13:17:20 +0200 Subject: [PATCH 153/202] Fix typo --- README.md | 8 ++++---- snippets/element-is-visible-in-viewport.md | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b838a8f6c..3d80a141b 100644 --- a/README.md +++ b/README.md @@ -329,8 +329,8 @@ const dropElements = (arr,func) => { [⬆ back to top](#table-of-contents) ### Element is visible in viewport -Use `Element.getBoundingClientRect()` and the `window.inner(Width|Height)` values -to determine if a given element is visible in the viewport. +Use `Element.getBoundingClientRect()` and the `window.inner(Width|Height)` values +to determine if a given element is visible in the viewport. Omit the second argument to determine if the element is entirely visible, or specify `true` to determine if it is partially visible. @@ -343,8 +343,8 @@ const elementIsVisibleInViewport = (el, partiallyVisible = false) => { : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; } // e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10} -// elementIsInViewport(el) -> false (not fully visible) -// elementIsInViewport(el, true) -> true (partially visible) +// elementIsVisibleInViewport(el) -> false (not fully visible) +// elementIsVisibleInViewport(el, true) -> true (partially visible) ``` [⬆ back to top](#table-of-contents) diff --git a/snippets/element-is-visible-in-viewport.md b/snippets/element-is-visible-in-viewport.md index 68a690d0d..70ff83134 100644 --- a/snippets/element-is-visible-in-viewport.md +++ b/snippets/element-is-visible-in-viewport.md @@ -1,7 +1,7 @@ ### Element is visible in viewport -Use `Element.getBoundingClientRect()` and the `window.inner(Width|Height)` values -to determine if a given element is visible in the viewport. +Use `Element.getBoundingClientRect()` and the `window.inner(Width|Height)` values +to determine if a given element is visible in the viewport. Omit the second argument to determine if the element is entirely visible, or specify `true` to determine if it is partially visible. @@ -14,6 +14,6 @@ const elementIsVisibleInViewport = (el, partiallyVisible = false) => { : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; } // e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10} -// elementIsInViewport(el) -> false (not fully visible) -// elementIsInViewport(el, true) -> true (partially visible) +// elementIsVisibleInViewport(el) -> false (not fully visible) +// elementIsVisibleInViewport(el, true) -> true (partially visible) ``` From ab26207a7978f1153d8b75c522c6387ffe045cd6 Mon Sep 17 00:00:00 2001 From: Alberto Schiabel Date: Thu, 14 Dec 2017 12:43:44 +0100 Subject: [PATCH 154/202] Fixed typo Is boolean => Is function --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d80a141b..1fb118d6f 100644 --- a/README.md +++ b/README.md @@ -562,7 +562,7 @@ const isBoolean = val => typeof val === 'boolean'; ``` [⬆ back to top](#table-of-contents) -### Is boolean +### Is function Use `typeof` to check if a value is classified as a function primitive. From 6ddb9d349c746b5de618cdab401d88718b10a449 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 13:46:06 +0200 Subject: [PATCH 155/202] Update is-function.md --- snippets/is-function.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/is-function.md b/snippets/is-function.md index a406ee543..d4247a512 100644 --- a/snippets/is-function.md +++ b/snippets/is-function.md @@ -1,4 +1,4 @@ -### Is boolean +### Is function Use `typeof` to check if a value is classified as a function primitive. From b44463501a490f9fa72ea3bd7c2a7ff290170c18 Mon Sep 17 00:00:00 2001 From: Leandro Franciscato Date: Thu, 14 Dec 2017 10:36:36 -0200 Subject: [PATCH 156/202] Adding get-days-difference-between-dates --- README.md | 13 ++++++++++++- snippets/get-days-difference-between-dates.md | 8 ++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 snippets/get-days-difference-between-dates.md diff --git a/README.md b/README.md index 1fb118d6f..9552e9f29 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ * [Fibonacci array generator](#fibonacci-array-generator) * [Filter out non unique values in an array](#filter-out-non-unique-values-in-an-array) * [Flatten array](#flatten-array) +* [Get days difference between dates](#get-days-difference-between-dates) * [Get max value from array](#get-max-value-from-array) * [Get min value from array](#get-min-value-from-array) * [Get native type of value](#get-native-type-of-value) @@ -66,7 +67,7 @@ * [Promisify](#promisify) * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -412,6 +413,16 @@ const flatten = arr => arr.reduce((a, v) => a.concat(v), []); // flatten([1,[2],3,4]) -> [1,2,3,4] ``` +[⬆ back to top](#table-of-contents) +### Get Days Difference Between Dates + +Returns the number of days between two Dates. + +```js +const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24); +//getDaysDiffBetweenDates(new Date("2017-12-13"), new Date("2017-12-22")) -> 9 +``` + [⬆ back to top](#table-of-contents) ### Get max value from array diff --git a/snippets/get-days-difference-between-dates.md b/snippets/get-days-difference-between-dates.md new file mode 100644 index 000000000..152cd7167 --- /dev/null +++ b/snippets/get-days-difference-between-dates.md @@ -0,0 +1,8 @@ +### Get Days Difference Between Dates + +Returns the number of days between two Dates. + +```js +const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24); +//getDaysDiffBetweenDates(new Date("2017-12-13"), new Date("2017-12-22")) -> 9 +``` From e44fef2a2a24b5ba01d2e985365837e6ba8bf15f Mon Sep 17 00:00:00 2001 From: Christian Bender Date: Thu, 14 Dec 2017 13:48:57 +0100 Subject: [PATCH 157/202] changed I changed 'javascript' in 'js' --- snippets/collatz.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/collatz.md b/snippets/collatz.md index 120f96e27..f92718b6c 100644 --- a/snippets/collatz.md +++ b/snippets/collatz.md @@ -3,7 +3,7 @@ If n even then returns **n/2** otherwise (n is odd) **3n+1**. It uses the ternary operator. -``` javascript +``` js const collatz = n => (n % 2 == 0) ? (n/2) : (3*n+1); // collatz(8) --> 4 // collatz(5) --> 16 From 421f4f46a8b0e832924edb6d58729af9f240b8f7 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 14:51:44 +0200 Subject: [PATCH 158/202] Update and rename collatz.md to collatz-algorithm.md --- snippets/collatz-algorithm.md | 9 +++++++++ snippets/collatz.md | 11 ----------- 2 files changed, 9 insertions(+), 11 deletions(-) create mode 100644 snippets/collatz-algorithm.md delete mode 100644 snippets/collatz.md diff --git a/snippets/collatz-algorithm.md b/snippets/collatz-algorithm.md new file mode 100644 index 000000000..730bdd9e3 --- /dev/null +++ b/snippets/collatz-algorithm.md @@ -0,0 +1,9 @@ +### Collatz algorithm + +If `n` is even, return `n/2`. Otherwise return `3n+1`. + +```js +const collatz = n => (n % 2 == 0) ? (n/2) : (3*n+1); +// collatz(8) --> 4 +// collatz(5) --> 16 +``` diff --git a/snippets/collatz.md b/snippets/collatz.md deleted file mode 100644 index f92718b6c..000000000 --- a/snippets/collatz.md +++ /dev/null @@ -1,11 +0,0 @@ -### Collatz algorithm - -If n even then returns **n/2** otherwise (n is odd) **3n+1**. -It uses the ternary operator. - -``` js - const collatz = n => (n % 2 == 0) ? (n/2) : (3*n+1); - // collatz(8) --> 4 - // collatz(5) --> 16 - -``` \ No newline at end of file From 61dc0394df7763176adb2bf7b6704f3d306626dc Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 14:53:37 +0200 Subject: [PATCH 159/202] Build README --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 1fb118d6f..2fccd2d85 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ * [Chain asynchronous functions](#chain-asynchronous-functions) * [Check for palindrome](#check-for-palindrome) * [Chunk array](#chunk-array) +* [Collatz algorithm](#collatz-algorithm) * [Compact](#compact) * [Count occurrences of a value in array](#count-occurrences-of-a-value-in-array) * [Current URL](#current-url) @@ -230,6 +231,17 @@ const chunk = (arr, size) => // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` +[⬆ back to top](#table-of-contents) +### Collatz algorithm + +If `n` is even, return `n/2`. Otherwise return `3n+1`. + +```js +const collatz = n => (n % 2 == 0) ? (n/2) : (3*n+1); +// collatz(8) --> 4 +// collatz(5) --> 16 +``` + [⬆ back to top](#table-of-contents) ### Compact From 4e3c5a4808b0bf6fa8dcfe0d6559be92fc5fb943 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 15:41:40 +0200 Subject: [PATCH 160/202] Create fill-array.md --- snippets/fill-array.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 snippets/fill-array.md diff --git a/snippets/fill-array.md b/snippets/fill-array.md new file mode 100644 index 000000000..a08c4362e --- /dev/null +++ b/snippets/fill-array.md @@ -0,0 +1,10 @@ +### Fill array + +Use `Array.map()` to map values between `start` (inclusive) and `end` (exclusive) to `value`. +Omit `start` to start at the first element and/or `end` to finish at the last. + +```js +const fillArray = (arr, value, start = 0, end = arr.length) => + arr.map((v,i) => i>=start && i [1,'8','8',4] +``` From c76c245b634f928042e349754ccdf4e406cc0469 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 16:10:43 +0200 Subject: [PATCH 161/202] Create flatten-array-up-to-depth.md In reference to #100. --- snippets/flatten-array-up-to-depth.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 snippets/flatten-array-up-to-depth.md diff --git a/snippets/flatten-array-up-to-depth.md b/snippets/flatten-array-up-to-depth.md new file mode 100644 index 000000000..d28af98fb --- /dev/null +++ b/snippets/flatten-array-up-to-depth.md @@ -0,0 +1,13 @@ +### Flatten array up to depth + +Use recursion, decrementing `depth` by 1 for each level of depth. +Use `Array.reduce()` and `Array.concat()` to merge elements or arrays. +Base case, for `depth` equal to `1` stops recursion. +Omit the second element, `depth` to flatten only to a depth of `1` (single flatten). + +```js +const flattenDepth = (arr, depth = 1) => + depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth (v, depth-1) : v), []) + : arr.reduce((a,v) => a.concat(v),[]); +// flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5] +``` From f143fb3d744e21e68154f382c21ee8058a89be06 Mon Sep 17 00:00:00 2001 From: Elder Henrique Souza Date: Thu, 14 Dec 2017 12:57:03 -0200 Subject: [PATCH 162/202] minor refactor to group by --- snippets/group-by.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/snippets/group-by.md b/snippets/group-by.md index ab833c9d2..44505eb2f 100644 --- a/snippets/group-by.md +++ b/snippets/group-by.md @@ -5,10 +5,9 @@ Use `Array.reduce()` to create an object, where the keys are produced from the m ```js const groupBy = (arr, func) => - (typeof func === 'function' ? arr.map(func) : arr.map(val => val[func])) - .reduce((acc, val, i) => { - acc[val] = acc[val] === undefined ? [arr[i]] : acc[val].concat(arr[i]); return acc; - }, {}); + arr + .map(typeof func === 'function' ? func : val => val[func]) + .reduce((acc, val, i) => { acc[val] = (acc[val] || []).concat(arr[i]); return acc; }, {}) // groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]} // groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} ``` From 537775168ddc1a27f4889883e96082f71d49abf5 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 16:59:30 +0200 Subject: [PATCH 163/202] Update group-by.md --- snippets/group-by.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/snippets/group-by.md b/snippets/group-by.md index 44505eb2f..ec8074ea2 100644 --- a/snippets/group-by.md +++ b/snippets/group-by.md @@ -5,9 +5,8 @@ Use `Array.reduce()` to create an object, where the keys are produced from the m ```js const groupBy = (arr, func) => - arr - .map(typeof func === 'function' ? func : val => val[func]) - .reduce((acc, val, i) => { acc[val] = (acc[val] || []).concat(arr[i]); return acc; }, {}) + arr.map(typeof func === 'function' ? func : val => val[func]) + .reduce((acc, val, i) => { acc[val] = (acc[val] || []).concat(arr[i]); return acc; }, {}); // groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]} // groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} ``` From aec1f85ee9b36beea50e37d85e8153b5d43ea9a4 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 17:02:10 +0200 Subject: [PATCH 164/202] Build README --- README.md | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2fccd2d85..65a72b1a0 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,9 @@ * [Even or odd number](#even-or-odd-number) * [Factorial](#factorial) * [Fibonacci array generator](#fibonacci-array-generator) +* [Fill array](#fill-array) * [Filter out non unique values in an array](#filter-out-non-unique-values-in-an-array) +* [Flatten array up to depth](#flatten-array-up-to-depth) * [Flatten array](#flatten-array) * [Get max value from array](#get-max-value-from-array) * [Get min value from array](#get-min-value-from-array) @@ -404,6 +406,18 @@ const fibonacci = n => // fibonacci(5) -> [0,1,1,2,3] ``` +[⬆ back to top](#table-of-contents) +### Fill array + +Use `Array.map()` to map values between `start` (inclusive) and `end` (exclusive) to `value`. +Omit `start` to start at the first element and/or `end` to finish at the last. + +```js +const fillArray = (arr, value, start = 0, end = arr.length) => + arr.map((v,i) => i>=start && i [1,'8','8',4] +``` + [⬆ back to top](#table-of-contents) ### Filter out non-unique values in an array @@ -414,6 +428,21 @@ const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexO // filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] ``` +[⬆ back to top](#table-of-contents) +### Flatten array up to depth + +Use recursion, decrementing `depth` by 1 for each level of depth. +Use `Array.reduce()` and `Array.concat()` to merge elements or arrays. +Base case, for `depth` equal to `1` stops recursion. +Omit the second element, `depth` to flatten only to a depth of `1` (single flatten). + +```js +const flattenDepth = (arr, depth = 1) => + depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth (v, depth-1) : v), []) + : arr.reduce((a,v) => a.concat(v),[]); +// flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5] +``` + [⬆ back to top](#table-of-contents) ### Flatten array @@ -488,10 +517,8 @@ Use `Array.reduce()` to create an object, where the keys are produced from the m ```js const groupBy = (arr, func) => - (typeof func === 'function' ? arr.map(func) : arr.map(val => val[func])) - .reduce((acc, val, i) => { - acc[val] = acc[val] === undefined ? [arr[i]] : acc[val].concat(arr[i]); return acc; - }, {}); + arr.map(typeof func === 'function' ? func : val => val[func]) + .reduce((acc, val, i) => { acc[val] = (acc[val] || []).concat(arr[i]); return acc; }, {}); // groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]} // groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} ``` From 8589f0c80e131fa74ca7aaa69f8350f02627c5aa Mon Sep 17 00:00:00 2001 From: Elder Henrique Souza Date: Thu, 14 Dec 2017 13:11:45 -0200 Subject: [PATCH 165/202] minor refactor to curry --- snippets/curry.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/snippets/curry.md b/snippets/curry.md index edb95461f..b47492721 100644 --- a/snippets/curry.md +++ b/snippets/curry.md @@ -6,13 +6,10 @@ Otherwise return a curried function `f` that expects the rest of the arguments. If you want to curry a function that accepts a variable number of arguments (a variadic function, e.g. `Math.min()`), you can optionally pass the number of arguments to the second parameter `arity`. ```js -const curry = (f, arity = f.length, next) => - (next = prevArgs => - nextArg => { - const args = [ ...prevArgs, nextArg ]; - return args.length >= arity ? f(...args) : next(args); - } - )([]); +const curry = (fn, arity = fn.length, ...args) => + arity <= args.length + ? fn(...args) + : curry.bind(null, fn, arity, ...args) // curry(Math.pow)(2)(10) -> 1024 // curry(Math.min, 3)(10)(50)(2) -> 2 ``` From a493fb984b16acb23bc8f8119b7b82bab726866e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Feje=C5=A1?= Date: Thu, 14 Dec 2017 16:25:35 +0100 Subject: [PATCH 166/202] Fix grammar and spelling --- CONTRIBUTING.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index db1670488..d2bdbf7e1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,9 +12,9 @@ Here's what you can do to help: ### Snippet submission and Pull request guidelines - **DO NOT MODIFY THE README.md FILE!** Make changes to individual snippet files. You can optionally run `npm run build-list` to update the README.md file automatically, based on the changes you have made. -- **Snippet filenames** must correspond to the title of the snippet. For example if your snippet is titled `### Awesome snippet` the filename should be `awesome-snippet.md`. +- **Snippet filenames** must correspond to the title of the snippet. For example, if your snippet is titled `### Awesome snippet` the filename should be `awesome-snippet.md`. - Use `kebab-case`, not `snake_case`. - - Avoid capitalization of words, except if the whole word is capitalized (e.g `URL` should be capitalized in the filename and the snippet title). + - Avoid capitalization of words, except if the whole word is capitalized (e.g. `URL` should be capitalized in the filename and the snippet title). - If there are parentheses in the title, add them to the filename (e.g. `awesome-snippet-(extra-awesome).md` if your snippet's title is `Awesome snippet (extra awesome)`). - **Snippet titles** should have only the first letter of the first word capitalized. Certain words can be in capitals (e.g. `URL`, `RGB`), but this is on a per-snippet basis. - All snippet titles must be prefixed with `###` and be at the very first line of your snippet. @@ -28,21 +28,21 @@ Here's what you can do to help: - Try to keep your snippets' code short and to the point. Use modern techniques and features. Make sure to test your code before submitting. - All snippets must be followed by one (more if necessary) test case after the code, on a new line, in the form of a comment, along with the expected output. The syntax for this is `myFunction('testInput') -> 'testOutput'`. Use multiline comments only if necessary. - Try to make your function name unique, so that it does not conflict with existing snippets. -- Snippets should be short (usually below 10 lines). If your snippet is longer than that, you can still submit it and we can help you shorten it or figure out ways to improve it. +- Snippets should be short (usually below 10 lines). If your snippet is longer than that, you can still submit it, and we can help you shorten it or figure out ways to improve it. - Snippets *should* solve real-world problems, no matter how simple. - Snippets *should* be abstract enough to be applied to different scenarios. -- It is not mandatory, but highly appreciated if you provide **test cases** and/or performance tests (we recommend using [jsPerf](https://jsperf.com/)). +- It is not mandatory but highly appreciated if you provide **test cases** and/or performance tests (we recommend using [jsPerf](https://jsperf.com/)). - You can start creating a new snippet, by using the [snippet template](snippet-template.md) to format your snippets. ### Additional guidelines and conventions regarding snippets - When describing snippets, refer to methods, using their full name. For example, use `Array.reduce()`, instead of `reduce()`. -- If your snippet contains argument with default parameters, explain what happens if they are ommited when calling the function and what the default case is. +- If your snippet contains argument with default parameters, explain what happens if they are omitted when calling the function and what the default case is. - If your snippet uses recursion, explain the base cases. - Always use `const functionName` for function definitions. -- Use variables only when necessary. Prefer `const` when the values are not altered after assignment, otherwise use `let`. Avoid using `var`. +- Use variables only when necessary. Prefer `const` when the values are not altered after assignment, otherwise, use `let`. Avoid using `var`. - Use `camelCase` for function and variable names if they consist of more than one word. -- Try to give meaningful names to variables. For example use `letter`, instead of `lt`. Some exceptions by convention are: +- Try to give meaningful names to variables. For example use `letter`, instead of `lt`. Some exceptions to convention are: - `arr` for arrays (usually as the snippet function's argument). - `str` for strings. - `n` for a numeric value (usually as the snippet function's argument). @@ -54,7 +54,7 @@ Here's what you can do to help: - `func` for function arguments. - `nums` for arrays of numbers. - Use `_` if your function takes no arguments or if an argument inside some function (e.g. `Array.reduce()`) is not used anywhere in your code. -- Specify default parameters for arguments, if necessary. It is preferred to put default parameters last, unless you have pretty good reason not to. +- Specify default parameters for arguments, if necessary. It is preferred to put default parameters last unless you have pretty good reason not to. - If your snippet's function takes variadic arguments, use `..args` (although in certain cases, it might be needed to use a different name). - If your snippet function's body is a single statement, omit the `return` keyword and use an expression instead. - Always use soft tabs (2 spaces), never hard tabs. @@ -72,5 +72,5 @@ Here's what you can do to help: - Use arrow functions as much as possible, except when you can't. - Use semicolons whenever necessary. If your snippet function's body is a single statement, return an expression and add a semicolon at the end. - Leave a single space after a comma (`,`) character. -- Try to strike a balance between readability, brevity and performance. +- Try to strike a balance between readability, brevity, and performance. - Never use `eval()`. Your snippet will be disqualified immediately. From 6bd0e08eef276264008bf0585d069a50a518aa17 Mon Sep 17 00:00:00 2001 From: Marcel Michau Date: Thu, 14 Dec 2017 17:53:32 +0200 Subject: [PATCH 167/202] Minor grammar fix in array-concatenation snippet & rebuilt README --- README.md | 4 ++-- snippets/array-concatenation.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 65a72b1a0..ba2c3d8bd 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ * [Promisify](#promisify) * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -110,7 +110,7 @@ const anagrams = str => { [⬆ back to top](#table-of-contents) ### Array concatenation -Use `Array.concat()` to concatenate and array with any additional arrays and/or values, specified in `args`. +Use `Array.concat()` to concatenate an array with any additional arrays and/or values, specified in `args`. ```js const arrayConcat = (arr, ...args) => arr.concat(...args); diff --git a/snippets/array-concatenation.md b/snippets/array-concatenation.md index b4e2fa205..992036905 100644 --- a/snippets/array-concatenation.md +++ b/snippets/array-concatenation.md @@ -1,6 +1,6 @@ ### Array concatenation -Use `Array.concat()` to concatenate and array with any additional arrays and/or values, specified in `args`. +Use `Array.concat()` to concatenate an array with any additional arrays and/or values, specified in `args`. ```js const arrayConcat = (arr, ...args) => arr.concat(...args); From 143b7f6a23e171bf80eae985add9beebb73e5748 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 17:56:12 +0200 Subject: [PATCH 168/202] Added tagger script, tagged snippets retroactively --- package-lock.json | 65 ++-- package.json | 5 +- scripts/tagger.js | 70 ++++ snippets/take.md | 1 - tag_database | 81 ++++ yarn.lock | 913 +++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 1080 insertions(+), 55 deletions(-) create mode 100644 scripts/tagger.js create mode 100644 tag_database diff --git a/package-lock.json b/package-lock.json index be8bcab8d..4344c4b9b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,16 +65,6 @@ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" }, - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=" - }, - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=" - }, "anymatch": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", @@ -333,21 +323,39 @@ "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=" }, "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, "requires": { - "ansi-styles": "1.1.0", + "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "has-ansi": "0.1.0", - "strip-ansi": "0.3.0", - "supports-color": "0.2.0" + "supports-color": "4.5.0" }, "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=" + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } } } }, @@ -442,7 +450,6 @@ "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.5.1.tgz", "integrity": "sha512-689HrwGw8Rbk1xtV9C4dY6TPJAvIYZbRbnKSAtfJ7tHqICFGoZ0PCWYjxfmerRyxBG0o3sbG3pe7N8vqPwIHuQ==", "requires": { - "chalk": "0.5.1", "commander": "2.6.0", "date-fns": "1.29.0", "lodash": "4.17.4", @@ -1346,14 +1353,6 @@ "function-bind": "1.1.1" } }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "requires": { - "ansi-regex": "0.2.1" - } - }, "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", @@ -2855,14 +2854,6 @@ "safe-buffer": "5.1.1" } }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "requires": { - "ansi-regex": "0.2.1" - } - }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", diff --git a/package.json b/package.json index a616c02d0..2e12c8aac 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,13 @@ "description": "A collection of useful Javascript snippets.", "version": "1.0.0", "main": "index.js", - "devDependencies": {}, + "devDependencies": { + "chalk": "^2.3.0" + }, "scripts": { "build-list": "node ./scripts/builder.js", "lint": "node ./scripts/lintSnippet.js", + "tag": "node ./scripts/tagger.js", "start": "concurrently --kill-others \"nodemon -e js,md -i README.md -x \\\"npm run build-list\\\"\" \"live-server ./build\"" }, "repository": { diff --git a/scripts/tagger.js b/scripts/tagger.js new file mode 100644 index 000000000..6e2329e28 --- /dev/null +++ b/scripts/tagger.js @@ -0,0 +1,70 @@ +var fs = require('fs-extra'); +var path = require('path'); +var chalk = require('chalk'); + +var snippetsPath = './snippets'; + +var snippets = {}, output = '', tagDbData = {}, missingTags = 0, tagDbStats = {}; + +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); +const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); + + +console.time('Tagger'); + +try { + var snippetFilenames = fs.readdirSync(snippetsPath); + snippetFilenames.sort((a, b) => { + a = a.toLowerCase(); + b = b.toLowerCase(); + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; + }); + for(var snippet of snippetFilenames){ + snippets[snippet] = fs.readFileSync(path.join(snippetsPath,snippet),'utf8'); + } +} +catch (err){ + console.log('Error during snippet loading: '+err); + process.exit(1); +} + +try { + tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').map(v => v.split(':').slice(0,2))); + // for(var tag of [...new Set(Object.entries(tagDbData).map(x => x[1]))]) + // tagDbStats[tag] = Object.values(tagDbData).filter(v => v === tag); + // console.log(tagDbStats); + tagDbStats = Object.entries(tagDbData).reduce((acc, val) => {acc.hasOwnProperty(val[1]) ? acc[val[1]]++ : acc[val[1]] = 1; return acc;}, {}); +} +catch (err){ + console.log('Error during tag database loading: '+err); + process.exit(1); +} + +try { + for(var snippet of Object.entries(snippets)) + if(tagDbData.hasOwnProperty(snippet[0].slice(0,-3)) && tagDbData[snippet[0].slice(0,-3)].trim()) + output += `${snippet[0].slice(0,-3)}:${tagDbData[snippet[0].slice(0,-3)].trim()}\n`; + else { + output += `${snippet[0].slice(0,-3)}:\n`; + missingTags++; + console.log(`${chalk.red('Tag missing:')} ${snippet[0].slice(0,-3)}`); + } + fs.writeFileSync('tag_database', output); +} +catch (err){ + console.log('Error during README generation: '+err); + process.exit(1); +} +console.log(`\n===Tag database statistics===`) +for(var tagData of Object.entries(tagDbStats).filter(v => v[0] !== 'undefined')){ + console.log(`${chalk.green(tagData[0])}: ${tagData[1]} snippets`); +} +console.log(`${chalk.blue('Untagged snippets:')} ${missingTags}\n`); + +console.timeEnd('Tagger'); diff --git a/snippets/take.md b/snippets/take.md index 80142031d..44d6ff0bc 100644 --- a/snippets/take.md +++ b/snippets/take.md @@ -4,7 +4,6 @@ Use `Array.slice()` to create a slice of the array with `n` elements taken from ```js const take = (arr, n = 1) => arr.slice(0, n); - // take([1, 2, 3], 5) -> [1, 2, 3] // take([1, 2, 3], 0) -> [] ``` diff --git a/tag_database b/tag_database new file mode 100644 index 000000000..5619a0369 --- /dev/null +++ b/tag_database @@ -0,0 +1,81 @@ +anagrams-of-string-(with-duplicates):string +array-concatenation:array +array-difference:array +array-intersection:array +array-union:array +average-of-array-of-numbers:array +bottom-visible:browser +capitalize-first-letter-of-every-word:string +capitalize-first-letter:string +chain-asynchronous-functions:function +check-for-palindrome:string +chunk-array:array +collatz-algorithm:math +compact:array +count-occurrences-of-a-value-in-array:array +current-URL:browser +curry:function +deep-flatten-array:array +distance-between-two-points:math +divisible-by-number:math +drop-elements-in-array:array +element-is-visible-in-viewport:browser +escape-regular-expression:utility +even-or-odd-number:math +factorial:math +fibonacci-array-generator:math +fill-array:array +filter-out-non-unique-values-in-an-array:array +flatten-array-up-to-depth:array +flatten-array:array +get-max-value-from-array:array +get-min-value-from-array:array +get-native-type-of-value:utility +get-scroll-position:browser +greatest-common-divisor-(GCD):math +group-by:array +hamming-distance:math +head-of-list:array +initial-of-list:array +initialize-array-with-range:array +initialize-array-with-values:array +is-array:utility +is-boolean:utility +is-function:utility +is-number:utility +is-string:utility +is-symbol:utility +last-of-list:array +measure-time-taken-by-function:utility +median-of-array-of-numbers:array +object-from-key-value-pairs:object +object-to-key-value-pairs:object +ordinal-suffix-of-number:utility +percentile:math +pick:array +pipe:function +powerset:math +promisify:function +random-integer-in-range:utility +random-number-in-range:utility +redirect-to-URL:browser +reverse-a-string:string +RGB-to-hexadecimal:utility +run-promises-in-series:function +scroll-to-top:browser +shuffle-array:array +similarity-between-arrays:array +sleep:function +sort-characters-in-string-(alphabetical):string +standard-deviation:math +sum-of-array-of-numbers:array +swap-values-of-two-variables:utility +tail-of-list:array +take:array +truncate-a-string:string +unique-values-of-array:array +URL-parameters:utility +UUID-generator:utility +validate-email:utility +validate-number:utility +value-or-default:utility diff --git a/yarn.lock b/yarn.lock index b5f1f6579..9dc4ac57e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13,7 +13,25 @@ accepts@~1.3.4: mime-types "~2.1.16" negotiator "0.6.1" -ajv@^4.9.1: +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" + +ajv-keywords@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + +ajv@^4.7.0, ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" dependencies: @@ -26,6 +44,10 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + ansi-regex@^0.2.0, ansi-regex@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9" @@ -42,6 +64,10 @@ ansi-styles@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + ansi-styles@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" @@ -92,10 +118,31 @@ arr-flatten@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" +array.prototype.find@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.4.tgz#556a5c5362c08648323ddaeb9de9d14bc1864c90" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -124,6 +171,14 @@ aws4@^1.2.1: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" +babel-code-frame@^6.16.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -191,6 +246,20 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" +builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -213,7 +282,17 @@ chalk@0.5.1: strip-ansi "^0.3.0" supports-color "^0.2.0" -chalk@^2.0.1: +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.1, chalk@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" dependencies: @@ -236,10 +315,24 @@ chokidar@^1.6.0, chokidar@^1.7.0: optionalDependencies: fsevents "^1.0.0" +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + cli-boxes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" +cli-cursor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -276,6 +369,14 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" +concat-stream@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + concurrently@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-3.5.1.tgz#ee8b60018bbe86b02df13e5249453c6ececd2521" @@ -313,6 +414,10 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -348,6 +453,12 @@ crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + dependencies: + es5-ext "^0.10.9" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -358,7 +469,11 @@ date-fns@^1.23.0: version "1.29.0" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" -debug@2.6.9, debug@^2.2.0, debug@^2.6.8: +debug-log@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" + +debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.6.8: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: @@ -374,6 +489,40 @@ deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + +deglob@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/deglob/-/deglob-2.1.0.tgz#4d44abe16ef32c779b4972bd141a80325029a14a" + dependencies: + find-root "^1.0.0" + glob "^7.0.5" + ignore "^3.0.9" + pkg-config "^1.1.0" + run-parallel "^1.1.2" + uniq "^1.0.1" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -394,6 +543,19 @@ detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" +doctrine@1.5.0, doctrine@^1.2.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075" + dependencies: + esutils "^2.0.2" + dot-prop@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" @@ -426,22 +588,256 @@ entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.7.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + +es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.37" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.37.tgz#0ee741d148b80069ba27d020393756af257defc3" + dependencies: + es6-iterator "~2.0.1" + es6-symbol "~3.1.1" + +es6-iterator@^2.0.1, es6-iterator@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + es6-promise@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-weak-map@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" -escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-config-semistandard@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-semistandard/-/eslint-config-semistandard-11.0.0.tgz#44eef7cfdfd47219e3a7b81b91b540e880bb2615" + +eslint-config-standard-jsx@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.1.tgz#cd4e463d0268e2d9e707f61f42f73f5b3333c642" + +eslint-config-standard@^10.2.1: + version "10.2.1" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz#c061e4d066f379dc17cd562c64e819b4dd454591" + +eslint-import-resolver-node@^0.2.0: + version "0.2.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c" + dependencies: + debug "^2.2.0" + object-assign "^4.0.1" + resolve "^1.1.6" + +eslint-module-utils@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + +eslint-plugin-import@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz#72ba306fad305d67c4816348a4699a4229ac8b4e" + dependencies: + builtin-modules "^1.1.1" + contains-path "^0.1.0" + debug "^2.2.0" + doctrine "1.5.0" + eslint-import-resolver-node "^0.2.0" + eslint-module-utils "^2.0.0" + has "^1.0.1" + lodash.cond "^4.3.0" + minimatch "^3.0.3" + pkg-up "^1.0.0" + +eslint-plugin-node@~4.2.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz#c04390ab8dbcbb6887174023d6f3a72769e63b97" + dependencies: + ignore "^3.0.11" + minimatch "^3.0.2" + object-assign "^4.0.1" + resolve "^1.1.7" + semver "5.3.0" + +eslint-plugin-promise@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz#78fbb6ffe047201627569e85a6c5373af2a68fca" + +eslint-plugin-react@~6.10.0: + version "6.10.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz#c5435beb06774e12c7db2f6abaddcbf900cd3f78" + dependencies: + array.prototype.find "^2.0.1" + doctrine "^1.2.2" + has "^1.0.1" + jsx-ast-utils "^1.3.4" + object.assign "^4.0.4" + +eslint-plugin-standard@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz#34d0c915b45edc6f010393c7eef3823b08565cf2" + +eslint@~3.19.0: + version "3.19.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" + dependencies: + babel-code-frame "^6.16.0" + chalk "^1.1.3" + concat-stream "^1.5.2" + debug "^2.1.1" + doctrine "^2.0.0" + escope "^3.6.0" + espree "^3.4.0" + esquery "^1.0.0" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + glob "^7.0.3" + globals "^9.14.0" + ignore "^3.2.0" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.7.5" + strip-bom "^3.0.0" + strip-json-comments "~2.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +espree@^3.4.0: + version "3.5.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca" + dependencies: + acorn "^5.2.1" + acorn-jsx "^3.0.0" + +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" + dependencies: + estraverse "^4.1.0" + object-assign "^4.0.1" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + dependencies: + d "1" + es5-ext "~0.10.14" + event-stream@latest, event-stream@~3.3.0: version "3.3.4" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" @@ -466,6 +862,10 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -492,12 +892,30 @@ extsprintf@1.3.0, extsprintf@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + faye-websocket@0.11.x: version "0.11.1" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" dependencies: websocket-driver ">=0.5.1" +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -522,6 +940,32 @@ finalhandler@0.5.1: statuses "~1.3.1" unpipe "~1.0.0" +find-root@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +flat-cache@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + for-in@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -532,6 +976,10 @@ for-own@^0.1.4: dependencies: for-in "^1.0.1" +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -588,6 +1036,10 @@ fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: mkdirp ">=0.5 0" rimraf "2" +function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -601,6 +1053,20 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +get-stdin@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -624,7 +1090,7 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@^7.0.5: +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -641,6 +1107,21 @@ global-dirs@^0.1.0: dependencies: ini "^1.3.4" +globals@^9.14.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" @@ -678,6 +1159,12 @@ has-ansi@^0.1.0: dependencies: ansi-regex "^0.2.0" +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" @@ -690,6 +1177,12 @@ has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" +has@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + hawk@3.1.3, hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -737,6 +1230,10 @@ ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" +ignore@^3.0.11, ignore@^3.0.9, ignore@^3.2.0: + version "3.3.7" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -752,7 +1249,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.3: +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -760,6 +1257,32 @@ ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +interpret@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -770,6 +1293,14 @@ is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -811,6 +1342,15 @@ is-installed-globally@^0.1.0: global-dirs "^0.1.0" is-path-inside "^1.0.0" +is-my-json-valid@^2.10.0: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" @@ -831,6 +1371,16 @@ is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + is-path-inside@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" @@ -845,10 +1395,24 @@ is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-resolvable@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4" + is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" @@ -857,6 +1421,10 @@ is-stream@^1.0.0, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -865,7 +1433,7 @@ is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" -isarray@1.0.0, isarray@~1.0.0: +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -883,6 +1451,17 @@ isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.5.1: + version "3.10.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -891,7 +1470,7 @@ json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" -json-stable-stringify@^1.0.1: +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" dependencies: @@ -911,6 +1490,10 @@ jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -920,6 +1503,10 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +jsx-ast-utils@^1.3.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz#3867213e8dd79bf1e8f2300c0cfc1efb182c0df1" + kind-of@^3.0.2: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -938,6 +1525,13 @@ latest-version@^3.0.0: dependencies: package-json "^4.0.0" +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + linkify-it@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.0.3.tgz#d94a4648f9b1c179d64fa97291268bdb6ce9434f" @@ -962,6 +1556,22 @@ live-server@^1.2.0: send latest serve-index "^1.7.2" +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + lodash._baseassign@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" @@ -1001,6 +1611,10 @@ lodash.assign@^3.0.0: lodash._createassigner "^3.0.0" lodash.keys "^3.0.0" +lodash.cond@^4.3.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" + lodash.defaults@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-3.1.2.tgz#c7308b18dbf8bc9372d701a73493c61192bd2e2c" @@ -1028,7 +1642,7 @@ lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" -lodash@^4.5.1: +lodash@^4.0.0, lodash@^4.3.0, lodash@^4.5.1: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -1099,7 +1713,7 @@ mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -1109,11 +1723,11 @@ minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.2.0: +minimist@^1.1.0, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" -"mkdirp@>=0.5 0", mkdirp@^0.5.1: +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -1137,10 +1751,18 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + nan@^2.3.0: version "2.8.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" @@ -1218,10 +1840,22 @@ oauth-sign@~0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" -object-assign@^4, object-assign@^4.1.0, object-assign@latest: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@latest: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-keys@^1.0.10, object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +object.assign@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.0.4.tgz#b1c9cc044ef1b9fe63606fc141abbb32e14730cc" + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.0" + object-keys "^1.0.10" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -1245,12 +1879,27 @@ once@^1.3.0, once@^1.3.3: dependencies: wrappy "1" +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + opn@latest: version "5.1.0" resolved "https://registry.yarnpkg.com/opn/-/opn-5.1.0.tgz#72ce2306a17dbea58ff1041853352b4a8fc77519" dependencies: is-wsl "^1.1.0" +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -1270,6 +1919,16 @@ p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" +p-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + package-json@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" @@ -1288,10 +1947,26 @@ parse-glob@^3.0.4: is-extglob "^1.0.0" is-glob "^2.0.0" +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + parseurl@~1.3.1, parseurl@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -1304,6 +1979,10 @@ path-key@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + pause-stream@0.0.11: version "0.0.11" resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" @@ -1314,10 +1993,59 @@ performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-conf@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.0.0.tgz#071c87650403bccfb9c627f58751bfe47c067279" + dependencies: + find-up "^2.0.0" + load-json-file "^2.0.0" + +pkg-config@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pkg-config/-/pkg-config-1.1.1.tgz#557ef22d73da3c8837107766c52eadabde298fe4" + dependencies: + debug-log "^1.0.0" + find-root "^1.0.0" + xtend "^4.0.1" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + +pkg-up@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26" + dependencies: + find-up "^1.0.0" + +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" @@ -1330,6 +2058,10 @@ process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + proxy-middleware@latest: version "0.15.0" resolved "https://registry.yarnpkg.com/proxy-middleware/-/proxy-middleware-0.15.0.tgz#a3fdf1befb730f951965872ac2f6074c61477a56" @@ -1372,7 +2104,7 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4: +readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" dependencies: @@ -1393,6 +2125,20 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + regex-cache@^0.4.2: version "0.4.4" resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" @@ -1451,12 +2197,50 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1: +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve@^1.1.6, resolve@^1.1.7: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" + dependencies: + path-parse "^1.0.5" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: glob "^7.0.5" +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + dependencies: + once "^1.3.0" + +run-parallel@^1.1.2: + version "1.1.6" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.6.tgz#29003c9a2163e01e2d2dfc90575f2c6c1d61a039" + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + rx@2.3.24: version "2.3.24" resolved "https://registry.yarnpkg.com/rx/-/rx-2.3.24.tgz#14f950a4217d7e35daa71bbcbe58eff68ea4b2b7" @@ -1465,12 +2249,31 @@ safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +semistandard@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/semistandard/-/semistandard-11.0.0.tgz#d2d9fc8ac393de21312195e006e50c8861391c47" + dependencies: + eslint "~3.19.0" + eslint-config-semistandard "^11.0.0" + eslint-config-standard "^10.2.1" + eslint-config-standard-jsx "4.0.1" + eslint-plugin-import "~2.2.0" + eslint-plugin-node "~4.2.2" + eslint-plugin-promise "~3.5.0" + eslint-plugin-react "~6.10.0" + eslint-plugin-standard "~3.0.1" + standard-engine "~7.0.0" + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" dependencies: semver "^5.0.3" +semver@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + semver@^5.0.3, semver@^5.1.0, semver@^5.3.0: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -1527,10 +2330,22 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" +shelljs@^0.7.5: + version "0.7.8" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + sntp@1.x.x: version "1.0.9" resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" @@ -1565,6 +2380,15 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" +standard-engine@~7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/standard-engine/-/standard-engine-7.0.0.tgz#ebb77b9c8fc2c8165ffa353bd91ba0dff41af690" + dependencies: + deglob "^2.1.0" + get-stdin "^5.0.1" + minimist "^1.1.0" + pkg-conf "^2.0.0" + "statuses@>= 1.3.1 < 2": version "1.4.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" @@ -1622,6 +2446,10 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -1634,6 +2462,10 @@ supports-color@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + supports-color@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" @@ -1646,6 +2478,17 @@ supports-color@^4.0.0: dependencies: has-flag "^2.0.0" +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + tar-pack@^3.4.0: version "3.4.1" resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" @@ -1673,7 +2516,11 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" -through@2, through@~2.3, through@~2.3.1: +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +through@2, through@^2.3.6, through@~2.3, through@~2.3.1: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -1707,6 +2554,16 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + uc.micro@^1.0.1, uc.micro@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192" @@ -1719,6 +2576,10 @@ undefsafe@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-0.0.3.tgz#ecca3a03e56b9af17385baac812ac83b994a962f" +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + unique-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" @@ -1761,6 +2622,12 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" +user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + dependencies: + os-homedir "^1.0.0" + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -1814,6 +2681,10 @@ widest-line@^1.0.0: dependencies: string-width "^1.0.1" +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -1826,10 +2697,20 @@ write-file-atomic@^2.0.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" +xtend@^4.0.0, xtend@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" From 2bcad76d6072aef29f65f782c199a0e0a921924c Mon Sep 17 00:00:00 2001 From: Marcel Michau Date: Thu, 14 Dec 2017 18:01:43 +0200 Subject: [PATCH 169/202] Renamed 'redirect-to-url.md' to 'redirect-to-URL.md' to keep case consistent with other headings --- README.md | 2 +- snippets/redirect-to-url.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ba2c3d8bd..bb4b99a85 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ * [Promisify](#promisify) * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) diff --git a/snippets/redirect-to-url.md b/snippets/redirect-to-url.md index dab1f775b..70356686f 100644 --- a/snippets/redirect-to-url.md +++ b/snippets/redirect-to-url.md @@ -5,6 +5,6 @@ Pass a second argument to simulate a link click (`true` - default) or an HTTP re ```js const redirect = (url, asLink = true) => - asLink ? window.location.href = url : window.location.replace(url); + asLink ? (window.location.href = url) : window.location.replace(url); // redirect('https://google.com') ``` From 89be90ad82800d4437f1bc22b404c85613a0e4d8 Mon Sep 17 00:00:00 2001 From: Marcel Michau Date: Thu, 14 Dec 2017 18:07:29 +0200 Subject: [PATCH 170/202] Undo Prettier auto-formatting --- snippets/{redirect-to-url.md => redirect-to-URL.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename snippets/{redirect-to-url.md => redirect-to-URL.md} (80%) diff --git a/snippets/redirect-to-url.md b/snippets/redirect-to-URL.md similarity index 80% rename from snippets/redirect-to-url.md rename to snippets/redirect-to-URL.md index 70356686f..dab1f775b 100644 --- a/snippets/redirect-to-url.md +++ b/snippets/redirect-to-URL.md @@ -5,6 +5,6 @@ Pass a second argument to simulate a link click (`true` - default) or an HTTP re ```js const redirect = (url, asLink = true) => - asLink ? (window.location.href = url) : window.location.replace(url); + asLink ? window.location.href = url : window.location.replace(url); // redirect('https://google.com') ``` From 907afe08e2166f88961833e0b0866d1332263d88 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 18:24:49 +0200 Subject: [PATCH 171/202] Categorization --- README.md | 1425 +++++++++++++++++++++++--------------------- scripts/builder.js | 31 +- scripts/tagger.js | 9 +- 3 files changed, 785 insertions(+), 680 deletions(-) diff --git a/README.md b/README.md index 65a72b1a0..46fcf2e14 100644 --- a/README.md +++ b/README.md @@ -9,105 +9,103 @@ ## Table of Contents -* [Anagrams of string (with duplicates)](#anagrams-of-string-with-duplicates) +### Array * [Array concatenation](#array-concatenation) * [Array difference](#array-difference) * [Array intersection](#array-intersection) * [Array union](#array-union) * [Average of array of numbers](#average-of-array-of-numbers) -* [Bottom visible](#bottom-visible) -* [Capitalize first letter of every word](#capitalize-first-letter-of-every-word) -* [Capitalize first letter](#capitalize-first-letter) -* [Chain asynchronous functions](#chain-asynchronous-functions) -* [Check for palindrome](#check-for-palindrome) * [Chunk array](#chunk-array) -* [Collatz algorithm](#collatz-algorithm) * [Compact](#compact) * [Count occurrences of a value in array](#count-occurrences-of-a-value-in-array) -* [Current URL](#current-url) -* [Curry](#curry) * [Deep flatten array](#deep-flatten-array) -* [Distance between two points](#distance-between-two-points) -* [Divisible by number](#divisible-by-number) * [Drop elements in array](#drop-elements-in-array) -* [Element is visible in viewport](#element-is-visible-in-viewport) -* [Escape regular expression](#escape-regular-expression) -* [Even or odd number](#even-or-odd-number) -* [Factorial](#factorial) -* [Fibonacci array generator](#fibonacci-array-generator) * [Fill array](#fill-array) * [Filter out non unique values in an array](#filter-out-non-unique-values-in-an-array) * [Flatten array up to depth](#flatten-array-up-to-depth) * [Flatten array](#flatten-array) * [Get max value from array](#get-max-value-from-array) * [Get min value from array](#get-min-value-from-array) -* [Get native type of value](#get-native-type-of-value) -* [Get scroll position](#get-scroll-position) -* [Greatest common divisor (GCD)](#greatest-common-divisor-gcd) * [Group by](#group-by) -* [Hamming distance](#hamming-distance) * [Head of list](#head-of-list) * [Initial of list](#initial-of-list) * [Initialize array with range](#initialize-array-with-range) * [Initialize array with values](#initialize-array-with-values) +* [Last of list](#last-of-list) +* [Median of array of numbers](#median-of-array-of-numbers) +* [Pick](#pick) +* [Shuffle array](#shuffle-array) +* [Similarity between arrays](#similarity-between-arrays) +* [Sum of array of numbers](#sum-of-array-of-numbers) +* [Tail of list](#tail-of-list) +* [Take](#take) +* [Unique values of array](#unique-values-of-array) + +### Browser +* [Bottom visible](#bottom-visible) +* [Current URL](#current-url) +* [Element is visible in viewport](#element-is-visible-in-viewport) +* [Get scroll position](#get-scroll-position) +* [Redirect to URL](#redirect-to-url) +* [Scroll to top](#scroll-to-top) + +### Function +* [Chain asynchronous functions](#chain-asynchronous-functions) +* [Curry](#curry) +* [Pipe](#pipe) +* [Promisify](#promisify) +* [Run promises in series](#run-promises-in-series) +* [Sleep](#sleep) + +### Math +* [Collatz algorithm](#collatz-algorithm) +* [Distance between two points](#distance-between-two-points) +* [Divisible by number](#divisible-by-number) +* [Even or odd number](#even-or-odd-number) +* [Factorial](#factorial) +* [Fibonacci array generator](#fibonacci-array-generator) +* [Greatest common divisor (GCD)](#greatest-common-divisor-gcd) +* [Hamming distance](#hamming-distance) +* [Percentile](#percentile) +* [Powerset](#powerset) +* [Standard deviation](#standard-deviation) + +### Object +* [Object from key value pairs](#object-from-key-value-pairs) +* [Object to key value pairs](#object-to-key-value-pairs) + +### String +* [Anagrams of string (with duplicates)](#anagrams-of-string-with-duplicates) +* [Capitalize first letter of every word](#capitalize-first-letter-of-every-word) +* [Capitalize first letter](#capitalize-first-letter) +* [Check for palindrome](#check-for-palindrome) +* [Reverse a string](#reverse-a-string) +* [Sort characters in string (alphabetical)](#sort-characters-in-string-alphabetical) +* [Truncate a string](#truncate-a-string) + +### Utility +* [Escape regular expression](#escape-regular-expression) +* [Get native type of value](#get-native-type-of-value) * [Is array](#is-array) * [Is boolean](#is-boolean) * [Is function](#is-function) * [Is number](#is-number) * [Is string](#is-string) * [Is symbol](#is-symbol) -* [Last of list](#last-of-list) * [Measure time taken by function](#measure-time-taken-by-function) -* [Median of array of numbers](#median-of-array-of-numbers) -* [Object from key value pairs](#object-from-key-value-pairs) -* [Object to key value pairs](#object-to-key-value-pairs) * [Ordinal suffix of number](#ordinal-suffix-of-number) -* [Percentile](#percentile) -* [Pick](#pick) -* [Pipe](#pipe) -* [Powerset](#powerset) -* [Promisify](#promisify) * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) -* [Redirect to URL](#redirect-to-url) -* [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) -* [Run promises in series](#run-promises-in-series) -* [Scroll to top](#scroll-to-top) -* [Shuffle array](#shuffle-array) -* [Similarity between arrays](#similarity-between-arrays) -* [Sleep](#sleep) -* [Sort characters in string (alphabetical)](#sort-characters-in-string-alphabetical) -* [Standard deviation](#standard-deviation) -* [Sum of array of numbers](#sum-of-array-of-numbers) * [Swap values of two variables](#swap-values-of-two-variables) -* [Tail of list](#tail-of-list) -* [Take](#take) -* [Truncate a string](#truncate-a-string) -* [Unique values of array](#unique-values-of-array) * [URL parameters](#url-parameters) * [UUID generator](#uuid-generator) * [Validate email](#validate-email) * [Validate number](#validate-number) * [Value or default](#value-or-default) -### Anagrams of string (with duplicates) +## Array -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)), []); -}; -// anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] -``` - -[⬆ back to top](#table-of-contents) ### Array concatenation Use `Array.concat()` to concatenate and array with any additional arrays and/or values, specified in `args`. @@ -118,6 +116,7 @@ const arrayConcat = (arr, ...args) => arr.concat(...args); ``` [⬆ back to top](#table-of-contents) + ### Array difference Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. @@ -128,6 +127,7 @@ const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has ``` [⬆ back to top](#table-of-contents) + ### Array intersection Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. @@ -138,6 +138,7 @@ const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.ha ``` [⬆ back to top](#table-of-contents) + ### Array union Create a `Set` with all values of `a` and `b` and convert to an array. @@ -148,6 +149,7 @@ const union = (a, b) => Array.from(new Set([...a, ...b])) ``` [⬆ back to top](#table-of-contents) + ### Average of array of numbers Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. @@ -158,69 +160,7 @@ const average = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length; ``` [⬆ back to top](#table-of-contents) -### Bottom visible -Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible. - -```js -const bottomVisible = _ => - document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; -// bottomVisible() -> true -``` - -[⬆ back to top](#table-of-contents) -### Capitalize first letter of every word - -Use `replace()` to match the first character of each word and `toUpperCase()` to capitalize it. - -```js -const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); -// capitalizeEveryWord('hello world!') -> 'Hello World!' -``` - -[⬆ back to top](#table-of-contents) -### Capitalize first letter - -Use `slice(0,1)` and `toUpperCase()` to capitalize first letter, `slice(1)` to get the rest of the string. -Omit the `lowerRest` parameter to keep the rest of the string intact, or set it to `true` to convert to lower case. - -```js -const capitalize = (str, lowerRest = false) => - str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); -// capitalize('myName', true) -> 'Myname' -``` - -[⬆ back to top](#table-of-contents) -### Chain asynchronous functions - -Loop through an array of functions containing asynchronous events, calling `next` when each asynchronous event has completed. - -```js -const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); }; -/* -chainAsync([ - next => { console.log('0 seconds'); setTimeout(next, 1000); }, - next => { console.log('1 second'); setTimeout(next, 1000); }, - next => { console.log('2 seconds'); } -]) -*/ -``` - -[⬆ back to top](#table-of-contents) -### Check for palindrome - -Convert string `toLowerCase()` and use `replace()` to remove non-alphanumeric characters from it. -Then, `split('')` into individual characters, `reverse()`, `join('')` and compare to the original, unreversed string, after converting it `tolowerCase()`. - -```js -const palindrome = str => { - const s = str.toLowerCase().replace(/[\W_]/g,''); - return s === s.split('').reverse().join(''); -} -// palindrome('taco cat') -> true - ``` - -[⬆ back to top](#table-of-contents) ### Chunk array Use `Array.from()` to create a new array, that fits the number of chunks that will be produced. @@ -234,17 +174,7 @@ const chunk = (arr, size) => ``` [⬆ back to top](#table-of-contents) -### Collatz algorithm -If `n` is even, return `n/2`. Otherwise return `3n+1`. - -```js -const collatz = n => (n % 2 == 0) ? (n/2) : (3*n+1); -// collatz(8) --> 4 -// collatz(5) --> 16 -``` - -[⬆ back to top](#table-of-contents) ### Compact Use `Array.filter()` to filter out falsey values (`false`, `null`, `0`, `""`, `undefined`, and `NaN`). @@ -255,6 +185,7 @@ const compact = (arr) => arr.filter(v => v); ``` [⬆ back to top](#table-of-contents) + ### Count occurrences of a value in array Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. @@ -265,36 +196,7 @@ const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + ``` [⬆ back to top](#table-of-contents) -### Current URL -Use `window.location.href` to get current URL. - -```js -const currentUrl = _ => window.location.href; -// currentUrl() -> 'https://google.com' -``` - -[⬆ back to top](#table-of-contents) -### Curry - -Use recursion. -If the number of provided arguments (`args`) is sufficient, call the passed function `f`. -Otherwise return a curried function `f` that expects the rest of the arguments. -If you want to curry a function that accepts a variable number of arguments (a variadic function, e.g. `Math.min()`), you can optionally pass the number of arguments to the second parameter `arity`. - -```js -const curry = (f, arity = f.length, next) => - (next = prevArgs => - nextArg => { - const args = [ ...prevArgs, nextArg ]; - return args.length >= arity ? f(...args) : next(args); - } - )([]); -// curry(Math.pow)(2)(10) -> 1024 -// curry(Math.min, 3)(10)(50)(2) -> 2 -``` - -[⬆ back to top](#table-of-contents) ### Deep flatten array Use recursion. @@ -307,26 +209,7 @@ const deepFlatten = arr => ``` [⬆ back to top](#table-of-contents) -### Distance between two points -Use `Math.hypot()` to calculate the Euclidean distance between two points. - -```js -const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); -// distance(1,1, 2,3) -> 2.23606797749979 -``` - -[⬆ back to top](#table-of-contents) -### Divisible by number - -Use the modulo operator (`%`) to check if the remainder is equal to `0`. - -```js -const isDivisible = (dividend, divisor) => dividend % divisor === 0; -// isDivisible(6,3) -> true -``` - -[⬆ back to top](#table-of-contents) ### Drop elements in array Loop through the array, using `Array.shift()` to drop the first element of the array until the returned value from the function is `true`. @@ -341,6 +224,274 @@ const dropElements = (arr,func) => { ``` [⬆ back to top](#table-of-contents) + +### Fill array + +Use `Array.map()` to map values between `start` (inclusive) and `end` (exclusive) to `value`. +Omit `start` to start at the first element and/or `end` to finish at the last. + +```js +const fillArray = (arr, value, start = 0, end = arr.length) => + arr.map((v,i) => i>=start && i [1,'8','8',4] +``` + +[⬆ back to top](#table-of-contents) + +### Filter out non-unique values in an array + +Use `Array.filter()` for an array containing only the unique values. + +```js +const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); +// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] +``` + +[⬆ back to top](#table-of-contents) + +### Flatten array up to depth + +Use recursion, decrementing `depth` by 1 for each level of depth. +Use `Array.reduce()` and `Array.concat()` to merge elements or arrays. +Base case, for `depth` equal to `1` stops recursion. +Omit the second element, `depth` to flatten only to a depth of `1` (single flatten). + +```js +const flattenDepth = (arr, depth = 1) => + depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth (v, depth-1) : v), []) + : arr.reduce((a,v) => a.concat(v),[]); +// flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5] +``` + +[⬆ back to top](#table-of-contents) + +### Flatten array + +Use `Array.reduce()` to get all elements inside the array and `concat()` to flatten them. + +```js +const flatten = arr => arr.reduce((a, v) => a.concat(v), []); +// flatten([1,[2],3,4]) -> [1,2,3,4] +``` + +[⬆ back to top](#table-of-contents) + +### Get max value from array + +Use `Math.max()` combined with the spread operator (`...`) to get the maximum value in the array. + +```js +const arrayMax = arr => Math.max(...arr); +// arrayMax([10, 1, 5]) -> 10 +``` + +[⬆ back to top](#table-of-contents) + +### Get min value from array + +Use `Math.min()` combined with the spread operator (`...`) to get the minimum value in the array. + +```js +const arrayMin = arr => Math.min(...arr); +// arrayMin([10, 1, 5]) -> 1 +``` + +[⬆ back to top](#table-of-contents) + +### Group by + +Use `Array.map()` to map the values of an array to a function or property name. +Use `Array.reduce()` to create an object, where the keys are produced from the mapped results. + +```js +const groupBy = (arr, func) => + arr.map(typeof func === 'function' ? func : val => val[func]) + .reduce((acc, val, i) => { acc[val] = (acc[val] || []).concat(arr[i]); return acc; }, {}); +// groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]} +// groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} +``` + +[⬆ back to top](#table-of-contents) + +### Head of list + +Use `arr[0]` to return the first element of the passed array. + +```js +const head = arr => arr[0]; +// head([1,2,3]) -> 1 +``` + +[⬆ back to top](#table-of-contents) + +### Initial of list + +Use `arr.slice(0,-1)`to return all but the last element of the array. + +```js +const initial = arr => arr.slice(0, -1); +// initial([1,2,3]) -> [1,2] +``` + +[⬆ back to top](#table-of-contents) + +### Initialize array with range + +Use `Array(end-start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. +You can omit `start` to use a default value of `0`. + +```js +const initializeArrayRange = (end, start = 0) => + Array.apply(null, Array(end - start)).map((v, i) => i + start); +// initializeArrayRange(5) -> [0,1,2,3,4] +``` + +[⬆ back to top](#table-of-contents) + +### Initialize array with values + +Use `Array(n)` to create an array of the desired length, `fill(v)` to fill it with the desired values. +You can omit `value` to use a default value of `0`. + +```js +const initializeArray = (n, value = 0) => Array(n).fill(value); +// initializeArray(5, 2) -> [2,2,2,2,2] +``` + +[⬆ back to top](#table-of-contents) + +### Last of list + +Use `arr.slice(-1)[0]` to get the last element of the given array. + +```js +const last = arr => arr.slice(-1)[0]; +// last([1,2,3]) -> 3 +``` + +[⬆ back to top](#table-of-contents) + +### Median of array of numbers + +Find the middle of the array, use `Array.sort()` to sort the values. +Return the number at the midpoint if `length` is odd, otherwise the average of the two middle numbers. + +```js +const median = arr => { + const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +}; +// median([5,6,50,1,-5]) -> 5 +// median([0,10,-2,7]) -> 3.5 +``` + +[⬆ back to top](#table-of-contents) + +### Pick + +Use `Array.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. + +```js +const pick = (obj, arr) => + arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); +// pick({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c']) -> { 'a': 1, 'c': 3 } +// pick(object, ['a', 'c'])['a'] -> 1 +``` + +[⬆ back to top](#table-of-contents) + +### Shuffle array + +Use `Array.sort()` to reorder elements, using `Math.random()` in the comparator. + +```js +const shuffle = arr => arr.sort(() => Math.random() - 0.5); +// shuffle([1,2,3]) -> [2,3,1] +``` + +[⬆ back to top](#table-of-contents) + +### Similarity between arrays + +Use `filter()` to remove values that are not part of `values`, determined using `includes()`. + +```js +const similarity = (arr, values) => arr.filter(v => values.includes(v)); +// similarity([1,2,3], [1,2,4]) -> [1,2] +``` + +[⬆ back to top](#table-of-contents) + +### Sum of array of numbers + +Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. + +```js +const sum = arr => arr.reduce((acc, val) => acc + val, 0); +// sum([1,2,3,4]) -> 10 +``` + +[⬆ back to top](#table-of-contents) + +### Tail of list + +Return `arr.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; +// tail([1,2,3]) -> [2,3] +// tail([1]) -> [1] +``` + +[⬆ back to top](#table-of-contents) + +### Take + +Use `Array.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); +// take([1, 2, 3], 5) -> [1, 2, 3] +// take([1, 2, 3], 0) -> [] +``` + +[⬆ back to top](#table-of-contents) + +### Unique values of array + +Use ES6 `Set` and the `...rest` operator to discard all duplicated values. + +```js +const unique = arr => [...new Set(arr)]; +// unique([1,2,2,3,4,4,5]) -> [1,2,3,4,5] +``` + +[⬆ back to top](#table-of-contents) +## Browser + +### Bottom visible + +Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible. + +```js +const bottomVisible = _ => + document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; +// bottomVisible() -> true +``` + +[⬆ back to top](#table-of-contents) + +### Current URL + +Use `window.location.href` to get current URL. + +```js +const currentUrl = _ => window.location.href; +// currentUrl() -> 'https://google.com' +``` + +[⬆ back to top](#table-of-contents) + ### Element is visible in viewport Use `Element.getBoundingClientRect()` and the `window.inner(Width|Height)` values @@ -362,129 +513,7 @@ const elementIsVisibleInViewport = (el, partiallyVisible = false) => { ``` [⬆ back to top](#table-of-contents) -### Escape regular expression -Use `replace()` to escape special characters. - -```js -const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -// escapeRegExp('(test)') -> \\(test\\) -``` - -[⬆ back to top](#table-of-contents) -### Even or odd number - -Checks whether a number is odd or even using the modulo (`%`) operator. -Returns `true` if the number is even, `false` if the number is odd. - -```js -const isEven = num => num % 2 === 0; -// isEven(3) -> false -``` - -[⬆ back to top](#table-of-contents) -### Factorial - -Use recursion. -If `n` is less than or equal to `1`, return `1`. -Otherwise, return the product of `n` and the factorial of `n - 1`. - -```js -const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); -// factorial(6) -> 720 -``` - -[⬆ back to top](#table-of-contents) -### Fibonacci array generator - -Create an empty array of the specific length, initializing the first two values (`0` and `1`). -Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. - -```js -const fibonacci = n => - Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []); -// fibonacci(5) -> [0,1,1,2,3] -``` - -[⬆ back to top](#table-of-contents) -### Fill array - -Use `Array.map()` to map values between `start` (inclusive) and `end` (exclusive) to `value`. -Omit `start` to start at the first element and/or `end` to finish at the last. - -```js -const fillArray = (arr, value, start = 0, end = arr.length) => - arr.map((v,i) => i>=start && i [1,'8','8',4] -``` - -[⬆ back to top](#table-of-contents) -### Filter out non-unique values in an array - -Use `Array.filter()` for an array containing only the unique values. - -```js -const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); -// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] -``` - -[⬆ back to top](#table-of-contents) -### Flatten array up to depth - -Use recursion, decrementing `depth` by 1 for each level of depth. -Use `Array.reduce()` and `Array.concat()` to merge elements or arrays. -Base case, for `depth` equal to `1` stops recursion. -Omit the second element, `depth` to flatten only to a depth of `1` (single flatten). - -```js -const flattenDepth = (arr, depth = 1) => - depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth (v, depth-1) : v), []) - : arr.reduce((a,v) => a.concat(v),[]); -// flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5] -``` - -[⬆ back to top](#table-of-contents) -### Flatten array - -Use `Array.reduce()` to get all elements inside the array and `concat()` to flatten them. - -```js -const flatten = arr => arr.reduce((a, v) => a.concat(v), []); -// flatten([1,[2],3,4]) -> [1,2,3,4] -``` - -[⬆ back to top](#table-of-contents) -### Get max value from array - -Use `Math.max()` combined with the spread operator (`...`) to get the maximum value in the array. - -```js -const arrayMax = arr => Math.max(...arr); -// arrayMax([10, 1, 5]) -> 10 -``` - -[⬆ back to top](#table-of-contents) -### Get min value from array - -Use `Math.min()` combined with the spread operator (`...`) to get the minimum value in the array. - -```js -const arrayMin = arr => Math.min(...arr); -// arrayMin([10, 1, 5]) -> 1 -``` - -[⬆ back to top](#table-of-contents) -### Get native type of value - -Returns lower-cased constructor name of value, "undefined" or "null" if value is undefined or null - -```js -const getType = v => - v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); -// getType(new Set([1,2,3])) -> "set" -``` - -[⬆ back to top](#table-of-contents) ### Get scroll position Use `pageXOffset` and `pageYOffset` if they are defined, otherwise `scrollLeft` and `scrollTop`. @@ -498,254 +527,67 @@ const getScrollPos = (el = window) => ``` [⬆ back to top](#table-of-contents) -### Greatest common divisor (GCD) + +undefined +[⬆ back to top](#table-of-contents) + +### Scroll to top + +Get distance from top using `document.documentElement.scrollTop` or `document.body.scrollTop`. +Scroll by a fraction of the distance from top. Use `window.requestAnimationFrame()` to animate the scrolling. + +```js +const scrollToTop = _ => { + const c = document.documentElement.scrollTop || document.body.scrollTop; + if (c > 0) { + window.requestAnimationFrame(scrollToTop); + window.scrollTo(0, c - c / 8); + } +}; +// scrollToTop() +``` + +[⬆ back to top](#table-of-contents) +## Function + +### Chain asynchronous functions + +Loop through an array of functions containing asynchronous events, calling `next` when each asynchronous event has completed. + +```js +const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); }; +/* +chainAsync([ + next => { console.log('0 seconds'); setTimeout(next, 1000); }, + next => { console.log('1 second'); setTimeout(next, 1000); }, + next => { console.log('2 seconds'); } +]) +*/ +``` + +[⬆ back to top](#table-of-contents) + +### Curry Use recursion. -Base case is when `y` equals `0`. In this case, return `x`. -Otherwise, return the GCD of `y` and the remainder of the division `x/y`. +If the number of provided arguments (`args`) is sufficient, call the passed function `f`. +Otherwise return a curried function `f` that expects the rest of the arguments. +If you want to curry a function that accepts a variable number of arguments (a variadic function, e.g. `Math.min()`), you can optionally pass the number of arguments to the second parameter `arity`. ```js -const gcd = (x, y) => !y ? x : gcd(y, x % y); -// gcd (8, 36) -> 4 +const curry = (f, arity = f.length, next) => + (next = prevArgs => + nextArg => { + const args = [ ...prevArgs, nextArg ]; + return args.length >= arity ? f(...args) : next(args); + } + )([]); +// curry(Math.pow)(2)(10) -> 1024 +// curry(Math.min, 3)(10)(50)(2) -> 2 ``` [⬆ back to top](#table-of-contents) -### Group by -Use `Array.map()` to map the values of an array to a function or property name. -Use `Array.reduce()` to create an object, where the keys are produced from the mapped results. - -```js -const groupBy = (arr, func) => - arr.map(typeof func === 'function' ? func : val => val[func]) - .reduce((acc, val, i) => { acc[val] = (acc[val] || []).concat(arr[i]); return acc; }, {}); -// groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]} -// groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} -``` - -[⬆ back to top](#table-of-contents) -### Hamming distance - -Use XOR operator (`^`) to find the bit difference between the two numbers, convert to binary string using `toString(2)`. -Count and return the number of `1`s in the string, using `match(/1/g)`. - -```js -const hammingDistance = (num1, num2) => - ((num1 ^ num2).toString(2).match(/1/g) || '').length; -// hammingDistance(2,3) -> 1 -``` - -[⬆ back to top](#table-of-contents) -### Head of list - -Use `arr[0]` to return the first element of the passed array. - -```js -const head = arr => arr[0]; -// head([1,2,3]) -> 1 -``` - -[⬆ back to top](#table-of-contents) -### Initial of list - -Use `arr.slice(0,-1)`to return all but the last element of the array. - -```js -const initial = arr => arr.slice(0, -1); -// initial([1,2,3]) -> [1,2] -``` - -[⬆ back to top](#table-of-contents) -### Initialize array with range - -Use `Array(end-start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. -You can omit `start` to use a default value of `0`. - -```js -const initializeArrayRange = (end, start = 0) => - Array.apply(null, Array(end - start)).map((v, i) => i + start); -// initializeArrayRange(5) -> [0,1,2,3,4] -``` - -[⬆ back to top](#table-of-contents) -### Initialize array with values - -Use `Array(n)` to create an array of the desired length, `fill(v)` to fill it with the desired values. -You can omit `value` to use a default value of `0`. - -```js -const initializeArray = (n, value = 0) => Array(n).fill(value); -// initializeArray(5, 2) -> [2,2,2,2,2] -``` - -[⬆ back to top](#table-of-contents) -### Is array - -Use `Array.isArray()` to check if a value is classified as an array. - -```js -const isArray = val => val && Array.isArray(val); -// isArray(null) -> false -// isArray([1]) -> true -``` - -[⬆ back to top](#table-of-contents) -### Is boolean - -Use `typeof` to check if a value is classified as a boolean primitive. - -```js -const isBoolean = val => typeof val === 'boolean'; -// isBoolean(null) -> false -// isBoolean(false) -> true -``` - -[⬆ back to top](#table-of-contents) -### Is function - -Use `typeof` to check if a value is classified as a function primitive. - -```js -const isFunction = val => val && typeof val === 'function'; -// isFunction('x') -> false -// isFunction(x => x) -> true -``` - -[⬆ back to top](#table-of-contents) -### Is number - -Use `typeof` to check if a value is classified as a number primitive. - -```js -const isNumber = val => typeof val === 'number'; -// isNumber('1') -> false -// isNumber(1) -> true -``` - -[⬆ back to top](#table-of-contents) -### Is string - -Use `typeof` to check if a value is classified as a string primitive. - -```js -const isString = val => typeof val === 'string'; -// isString(10) -> false -// isString('10') -> true -``` - -[⬆ back to top](#table-of-contents) -### Is symbol - -Use `typeof` to check if a value is classified as a symbol primitive. - -```js -const isSymbol = val => typeof val === 'symbol'; -// isSymbol('x') -> false -// isSymbol(Symbol('x')) -> true -``` - -[⬆ back to top](#table-of-contents) -### Last of list - -Use `arr.slice(-1)[0]` to get the last element of the given array. - -```js -const last = arr => arr.slice(-1)[0]; -// last([1,2,3]) -> 3 -``` - -[⬆ back to top](#table-of-contents) -### Measure time taken by function - -Use `performance.now()` to get start and end time for the function, `console.log()` the time taken. -Pass a callback function as the argument. - -```js -const timeTaken = callback => { - const t0 = performance.now(), r = callback(); - console.log(performance.now() - t0); - return r; -}; -// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) -``` - -[⬆ back to top](#table-of-contents) -### Median of array of numbers - -Find the middle of the array, use `Array.sort()` to sort the values. -Return the number at the midpoint if `length` is odd, otherwise the average of the two middle numbers. - -```js -const median = arr => { - const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); - return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; -}; -// median([5,6,50,1,-5]) -> 5 -// median([0,10,-2,7]) -> 3.5 -``` - -[⬆ back to top](#table-of-contents) -### Object from key-value pairs - -Use `Array.reduce()` to create and combine key-value pairs. - -```js -const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); -// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} -``` - -[⬆ back to top](#table-of-contents) -### Object to key-value pairs - -Use `Object.keys()` and `Array.map()` to iterate over the object's keys and produce an array with key-value pairs. - -```js -const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); -// objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) -``` - -[⬆ back to top](#table-of-contents) -### Ordinal suffix of number - -Use the modulo operator (`%`) to find values of single and tens digits. -Find which ordinal pattern digits match. -If digit is found in teens pattern, use teens ordinal. - -```js -const toOrdinalSuffix = num => { - const int = parseInt(num), digits = [(int % 10), (int % 100)], - ordinals = ["st", "nd", "rd", "th"], oPattern = [1,2,3,4], - tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] - return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; -} -// toOrdinalSuffix("123") -> "123rd" -``` - -[⬆ back to top](#table-of-contents) -### Percentile - -Use `Array.reduce()` to calculate how many numbers are below the value and how many are the same value and -apply the percentile formula. - -```js -const percentile = (arr, val) => - 100 * arr.reduce((acc,v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; -// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 - ``` - -[⬆ back to top](#table-of-contents) -### Pick - -Use `Array.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. - -```js -const pick = (obj, arr) => - arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); -// pick({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c']) -> { 'a': 1, 'c': 3 } -// pick(object, ['a', 'c'])['a'] -> 1 -``` - -[⬆ back to top](#table-of-contents) ### Pipe Use `Array.reduce()` to pass value through functions. @@ -756,17 +598,7 @@ const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg); ``` [⬆ back to top](#table-of-contents) -### Powerset -Use `Array.reduce()` combined with `Array.map()` to iterate over elements and combine into an array containing all combinations. - -```js -const powerset = arr => - arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); -// powerset([1,2]) -> [[], [1], [2], [2,1]] -``` - -[⬆ back to top](#table-of-contents) ### Promisify Use currying to return a function returning a `Promise` that calls the original function. @@ -786,59 +618,7 @@ const promisify = func => ``` [⬆ back to top](#table-of-contents) -### Random integer in range -Use `Math.random()` to generate a random number and map it to the desired range, using `Math.floor()` to make it an integer. - -```js -const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; -// randomIntegerInRange(0, 5) -> 2 -``` - -[⬆ back to top](#table-of-contents) -### Random number in range - -Use `Math.random()` to generate a random value, map it to the desired range using multiplication. - -```js -const randomInRange = (min, max) => Math.random() * (max - min) + min; -// randomInRange(2,10) -> 6.0211363285087005 -``` - -[⬆ back to top](#table-of-contents) -### Redirect to URL - -Use `window.location.href` or `window.location.replace()` to redirect to `url`. -Pass a second argument to simulate a link click (`true` - default) or an HTTP redirect (`false`). - -```js -const redirect = (url, asLink = true) => - asLink ? window.location.href = url : window.location.replace(url); -// redirect('https://google.com') -``` - -[⬆ back to top](#table-of-contents) -### Reverse a string - -Use array destructuring and `Array.reverse()` to reverse the order of the characters in the string. -Combine characters to get a string using `join('')`. - -```js -const reverseString = str => [...str].reverse().join(''); -// reverseString('foobar') -> 'raboof' -``` - -[⬆ back to top](#table-of-contents) -### RGB to hexadecimal - -Convert given RGB parameters to hexadecimal string using bitwise left-shift operator (`<<`) and `toString(16)`, then `padStart(6,'0')` to get a 6-digit hexadecimal value. - -```js -const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); -// rgbToHex(255, 165, 1) -> 'ffa501' -``` - -[⬆ back to top](#table-of-contents) ### Run promises in series Run an array of promises in series using `Array.reduce()` by creating a promise chain, where each promise returns the next promise when resolved. @@ -850,43 +630,7 @@ const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); ``` [⬆ back to top](#table-of-contents) -### Scroll to top -Get distance from top using `document.documentElement.scrollTop` or `document.body.scrollTop`. -Scroll by a fraction of the distance from top. Use `window.requestAnimationFrame()` to animate the scrolling. - -```js -const scrollToTop = _ => { - const c = document.documentElement.scrollTop || document.body.scrollTop; - if (c > 0) { - window.requestAnimationFrame(scrollToTop); - window.scrollTo(0, c - c / 8); - } -}; -// scrollToTop() -``` - -[⬆ back to top](#table-of-contents) -### Shuffle array - -Use `Array.sort()` to reorder elements, using `Math.random()` in the comparator. - -```js -const shuffle = arr => arr.sort(() => Math.random() - 0.5); -// shuffle([1,2,3]) -> [2,3,1] -``` - -[⬆ back to top](#table-of-contents) -### Similarity between arrays - -Use `filter()` to remove values that are not part of `values`, determined using `includes()`. - -```js -const similarity = (arr, values) => arr.filter(v => values.includes(v)); -// similarity([1,2,3], [1,2,4]) -> [1,2] -``` - -[⬆ back to top](#table-of-contents) ### Sleep Delay executing part of an `async` function, by putting it to sleep, returning a `Promise`. @@ -903,17 +647,131 @@ async function sleepyWork() { ``` [⬆ back to top](#table-of-contents) -### Sort characters in string (alphabetical) +## Math -Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, recombine using `join('')`. +### Collatz algorithm + +If `n` is even, return `n/2`. Otherwise return `3n+1`. ```js -const sortCharactersInString = str => - str.split('').sort((a, b) => a.localeCompare(b)).join(''); -// sortCharactersInString('cabbage') -> 'aabbceg' +const collatz = n => (n % 2 == 0) ? (n/2) : (3*n+1); +// collatz(8) --> 4 +// collatz(5) --> 16 ``` [⬆ back to top](#table-of-contents) + +### Distance between two points + +Use `Math.hypot()` to calculate the Euclidean distance between two points. + +```js +const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); +// distance(1,1, 2,3) -> 2.23606797749979 +``` + +[⬆ back to top](#table-of-contents) + +### Divisible by number + +Use the modulo operator (`%`) to check if the remainder is equal to `0`. + +```js +const isDivisible = (dividend, divisor) => dividend % divisor === 0; +// isDivisible(6,3) -> true +``` + +[⬆ back to top](#table-of-contents) + +### Even or odd number + +Checks whether a number is odd or even using the modulo (`%`) operator. +Returns `true` if the number is even, `false` if the number is odd. + +```js +const isEven = num => num % 2 === 0; +// isEven(3) -> false +``` + +[⬆ back to top](#table-of-contents) + +### Factorial + +Use recursion. +If `n` is less than or equal to `1`, return `1`. +Otherwise, return the product of `n` and the factorial of `n - 1`. + +```js +const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); +// factorial(6) -> 720 +``` + +[⬆ back to top](#table-of-contents) + +### Fibonacci array generator + +Create an empty array of the specific length, initializing the first two values (`0` and `1`). +Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. + +```js +const fibonacci = n => + Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []); +// fibonacci(5) -> [0,1,1,2,3] +``` + +[⬆ back to top](#table-of-contents) + +### Greatest common divisor (GCD) + +Use recursion. +Base case is when `y` equals `0`. In this case, return `x`. +Otherwise, return the GCD of `y` and the remainder of the division `x/y`. + +```js +const gcd = (x, y) => !y ? x : gcd(y, x % y); +// gcd (8, 36) -> 4 +``` + +[⬆ back to top](#table-of-contents) + +### Hamming distance + +Use XOR operator (`^`) to find the bit difference between the two numbers, convert to binary string using `toString(2)`. +Count and return the number of `1`s in the string, using `match(/1/g)`. + +```js +const hammingDistance = (num1, num2) => + ((num1 ^ num2).toString(2).match(/1/g) || '').length; +// hammingDistance(2,3) -> 1 +``` + +[⬆ back to top](#table-of-contents) + +### Percentile + +Use `Array.reduce()` to calculate how many numbers are below the value and how many are the same value and +apply the percentile formula. + +```js +const percentile = (arr, val) => + 100 * arr.reduce((acc,v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; +// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 + ``` + +[⬆ back to top](#table-of-contents) + +### Powerset + +Use `Array.reduce()` combined with `Array.map()` to iterate over elements and combine into an array containing all combinations. + +```js +const powerset = arr => + arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); +// powerset([1,2]) -> [[], [1], [2], [2,1]] +``` + +[⬆ back to top](#table-of-contents) + ### Standard deviation Use `Array.reduce()` to calculate the mean, variance and the sum of the variance of the values, the variance of the values, then @@ -933,49 +791,112 @@ const standardDeviation = (arr, usePopulation = false) => { ``` [⬆ back to top](#table-of-contents) -### Sum of array of numbers +## Object -Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. +### Object from key-value pairs + +Use `Array.reduce()` to create and combine key-value pairs. ```js -const sum = arr => arr.reduce((acc, val) => acc + val, 0); -// sum([1,2,3,4]) -> 10 +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); +// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} ``` [⬆ back to top](#table-of-contents) -### Swap values of two variables -Use array destructuring to swap values between two variables. +### Object to key-value pairs + +Use `Object.keys()` and `Array.map()` to iterate over the object's keys and produce an array with key-value pairs. ```js -[varA, varB] = [varB, varA]; -// [x, y] = [y, x] +const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); +// objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) ``` [⬆ back to top](#table-of-contents) -### Tail of list +## String -Return `arr.slice(1)` if the array's `length` is more than `1`, otherwise return the whole array. +### Anagrams of string (with 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 tail = arr => arr.length > 1 ? arr.slice(1) : arr; -// tail([1,2,3]) -> [2,3] -// tail([1]) -> [1] +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)), []); +}; +// anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` [⬆ back to top](#table-of-contents) -### Take -Use `Array.slice()` to create a slice of the array with `n` elements taken from the beginning. +### Capitalize first letter of every word + +Use `replace()` to match the first character of each word and `toUpperCase()` to capitalize it. ```js -const take = (arr, n = 1) => arr.slice(0, n); - -// take([1, 2, 3], 5) -> [1, 2, 3] -// take([1, 2, 3], 0) -> [] +const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); +// capitalizeEveryWord('hello world!') -> 'Hello World!' ``` [⬆ back to top](#table-of-contents) + +### Capitalize first letter + +Use `slice(0,1)` and `toUpperCase()` to capitalize first letter, `slice(1)` to get the rest of the string. +Omit the `lowerRest` parameter to keep the rest of the string intact, or set it to `true` to convert to lower case. + +```js +const capitalize = (str, lowerRest = false) => + str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); +// capitalize('myName', true) -> 'Myname' +``` + +[⬆ back to top](#table-of-contents) + +### Check for palindrome + +Convert string `toLowerCase()` and use `replace()` to remove non-alphanumeric characters from it. +Then, `split('')` into individual characters, `reverse()`, `join('')` and compare to the original, unreversed string, after converting it `tolowerCase()`. + +```js +const palindrome = str => { + const s = str.toLowerCase().replace(/[\W_]/g,''); + return s === s.split('').reverse().join(''); +} +// palindrome('taco cat') -> true + ``` + +[⬆ back to top](#table-of-contents) + +### Reverse a string + +Use array destructuring and `Array.reverse()` to reverse the order of the characters in the string. +Combine characters to get a string using `join('')`. + +```js +const reverseString = str => [...str].reverse().join(''); +// reverseString('foobar') -> 'raboof' +``` + +[⬆ back to top](#table-of-contents) + +### Sort characters in string (alphabetical) + +Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, recombine using `join('')`. + +```js +const sortCharactersInString = str => + str.split('').sort((a, b) => a.localeCompare(b)).join(''); +// sortCharactersInString('cabbage') -> 'aabbceg' +``` + +[⬆ back to top](#table-of-contents) + ### Truncate a String Determine if the string's `length` is greater than `num`. @@ -988,16 +909,181 @@ const truncate = (str, num) => ``` [⬆ back to top](#table-of-contents) -### Unique values of array +## Utility -Use ES6 `Set` and the `...rest` operator to discard all duplicated values. +### Escape regular expression + +Use `replace()` to escape special characters. ```js -const unique = arr => [...new Set(arr)]; -// unique([1,2,2,3,4,4,5]) -> [1,2,3,4,5] +const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +// escapeRegExp('(test)') -> \\(test\\) ``` [⬆ back to top](#table-of-contents) + +### Get native type of value + +Returns lower-cased constructor name of value, "undefined" or "null" if value is undefined or null + +```js +const getType = v => + v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); +// getType(new Set([1,2,3])) -> "set" +``` + +[⬆ back to top](#table-of-contents) + +### Is array + +Use `Array.isArray()` to check if a value is classified as an array. + +```js +const isArray = val => val && Array.isArray(val); +// isArray(null) -> false +// isArray([1]) -> true +``` + +[⬆ back to top](#table-of-contents) + +### Is boolean + +Use `typeof` to check if a value is classified as a boolean primitive. + +```js +const isBoolean = val => typeof val === 'boolean'; +// isBoolean(null) -> false +// isBoolean(false) -> true +``` + +[⬆ back to top](#table-of-contents) + +### Is function + +Use `typeof` to check if a value is classified as a function primitive. + +```js +const isFunction = val => val && typeof val === 'function'; +// isFunction('x') -> false +// isFunction(x => x) -> true +``` + +[⬆ back to top](#table-of-contents) + +### Is number + +Use `typeof` to check if a value is classified as a number primitive. + +```js +const isNumber = val => typeof val === 'number'; +// isNumber('1') -> false +// isNumber(1) -> true +``` + +[⬆ back to top](#table-of-contents) + +### Is string + +Use `typeof` to check if a value is classified as a string primitive. + +```js +const isString = val => typeof val === 'string'; +// isString(10) -> false +// isString('10') -> true +``` + +[⬆ back to top](#table-of-contents) + +### Is symbol + +Use `typeof` to check if a value is classified as a symbol primitive. + +```js +const isSymbol = val => typeof val === 'symbol'; +// isSymbol('x') -> false +// isSymbol(Symbol('x')) -> true +``` + +[⬆ back to top](#table-of-contents) + +### Measure time taken by function + +Use `performance.now()` to get start and end time for the function, `console.log()` the time taken. +Pass a callback function as the argument. + +```js +const timeTaken = callback => { + const t0 = performance.now(), r = callback(); + console.log(performance.now() - t0); + return r; +}; +// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) +``` + +[⬆ back to top](#table-of-contents) + +### Ordinal suffix of number + +Use the modulo operator (`%`) to find values of single and tens digits. +Find which ordinal pattern digits match. +If digit is found in teens pattern, use teens ordinal. + +```js +const toOrdinalSuffix = num => { + const int = parseInt(num), digits = [(int % 10), (int % 100)], + ordinals = ["st", "nd", "rd", "th"], oPattern = [1,2,3,4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; +} +// toOrdinalSuffix("123") -> "123rd" +``` + +[⬆ back to top](#table-of-contents) + +### Random integer in range + +Use `Math.random()` to generate a random number and map it to the desired range, using `Math.floor()` to make it an integer. + +```js +const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; +// randomIntegerInRange(0, 5) -> 2 +``` + +[⬆ back to top](#table-of-contents) + +### Random number in range + +Use `Math.random()` to generate a random value, map it to the desired range using multiplication. + +```js +const randomInRange = (min, max) => Math.random() * (max - min) + min; +// randomInRange(2,10) -> 6.0211363285087005 +``` + +[⬆ back to top](#table-of-contents) + +### RGB to hexadecimal + +Convert given RGB parameters to hexadecimal string using bitwise left-shift operator (`<<`) and `toString(16)`, then `padStart(6,'0')` to get a 6-digit hexadecimal value. + +```js +const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); +// rgbToHex(255, 165, 1) -> 'ffa501' +``` + +[⬆ back to top](#table-of-contents) + +### Swap values of two variables + +Use array destructuring to swap values between two variables. + +```js +[varA, varB] = [varB, varA]; +// [x, y] = [y, x] +``` + +[⬆ back to top](#table-of-contents) + ### URL parameters Use `match()` with an appropriate regular expression to get all key-value pairs, `Array.reduce()` to map and combine them into a single object. @@ -1012,6 +1098,7 @@ const getUrlParameters = url => ``` [⬆ back to top](#table-of-contents) + ### UUID generator Use `crypto` API to generate a UUID, compliant with [RFC4122](https://www.ietf.org/rfc/rfc4122.txt) version 4. @@ -1025,6 +1112,7 @@ const uuid = _ => ``` [⬆ back to top](#table-of-contents) + ### Validate email Use a regular experssion to check if the email is valid. @@ -1037,6 +1125,7 @@ const validateEmail = str => ``` [⬆ back to top](#table-of-contents) + ### Validate number Use `!isNaN` in combination with `parseFloat()` to check if the argument is a number. @@ -1049,6 +1138,7 @@ const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == ``` [⬆ back to top](#table-of-contents) + ### Value or default Returns value, or default value if passed value is `falsy`. @@ -1059,6 +1149,7 @@ const valueOrDefault = (value, d) => value || d; ``` [⬆ back to top](#table-of-contents) + ## Credits *Icons made by [Smashicons](https://www.flaticon.com/authors/smashicons) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/).* diff --git a/scripts/builder.js b/scripts/builder.js index 220469705..6a15e53a7 100644 --- a/scripts/builder.js +++ b/scripts/builder.js @@ -4,7 +4,10 @@ var path = require('path'); var snippetsPath = './snippets'; var staticPartsPath = './static-parts'; -var snippets = {}, startPart = '', endPart = '', output = ''; +var snippets = {}, startPart = '', endPart = '', output = '', tagDbData = {}; + +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); +const capitalize = (str, lowerRest = false) => str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); console.time('Builder'); @@ -39,14 +42,28 @@ catch (err){ process.exit(1); } +try { + tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').slice(0,-1).map(v => v.split(':').slice(0,2))); +} +catch (err){ + console.log('Error during tag database loading: '+err); + process.exit(1); +} + try { output += `${startPart+'\n'}`; - for(var snippet of Object.entries(snippets)) - output += `* [${snippet[0][0].toUpperCase() + snippet[0].replace(/-/g,' ').slice(1,snippet[0].length-3)}](#${snippet[0].slice(0,snippet[0].length-3).replace(/\(/g,'').replace(/\)/g,'').toLowerCase()})\n` - output += '\n'; - for(var snippet of Object.entries(snippets)) - output += `${snippet[1]+'\n[⬆ back to top](#table-of-contents)\n'}`; - output += `${endPart+'\n'}`; + for(var tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].sort((a,b) => a.localeCompare(b))){ + output +=`### ${capitalize(tag, true)}\n`; + for(var taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) + output += `* [${taggedSnippet[0][0].toUpperCase() + taggedSnippet[0].replace(/-/g,' ').slice(1)}](#${taggedSnippet[0].replace(/\(/g,'').replace(/\)/g,'').toLowerCase()})\n` + output += '\n'; + } + for(var tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].sort((a,b) => a.localeCompare(b))){ + output +=`## ${capitalize(tag, true)}\n`; + for(var taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) + output += `\n${snippets[taggedSnippet[0]+'.md']+'\n[⬆ back to top](#table-of-contents)\n'}`; + } + output += `\n${endPart+'\n'}`; fs.writeFileSync('README.md', output); } catch (err){ diff --git a/scripts/tagger.js b/scripts/tagger.js index 6e2329e28..ecebce50f 100644 --- a/scripts/tagger.js +++ b/scripts/tagger.js @@ -35,11 +35,8 @@ catch (err){ } try { - tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').map(v => v.split(':').slice(0,2))); - // for(var tag of [...new Set(Object.entries(tagDbData).map(x => x[1]))]) - // tagDbStats[tag] = Object.values(tagDbData).filter(v => v === tag); - // console.log(tagDbStats); - tagDbStats = Object.entries(tagDbData).reduce((acc, val) => {acc.hasOwnProperty(val[1]) ? acc[val[1]]++ : acc[val[1]] = 1; return acc;}, {}); + tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').slice(0,-1).map(v => v.split(':').slice(0,2))); + tagDbStats = Object.entries(tagDbData).sort((a,b) => a[1].localeCompare(b[1])).reduce((acc, val) => {acc.hasOwnProperty(val[1]) ? acc[val[1]]++ : acc[val[1]] = 1; return acc;}, {}); } catch (err){ console.log('Error during tag database loading: '+err); @@ -61,7 +58,7 @@ catch (err){ console.log('Error during README generation: '+err); process.exit(1); } -console.log(`\n===Tag database statistics===`) +console.log(`\n=== TAG STATS ===`) for(var tagData of Object.entries(tagDbStats).filter(v => v[0] !== 'undefined')){ console.log(`${chalk.green(tagData[0])}: ${tagData[1]} snippets`); } From 1c3d3f6290a2e06d077e741a79c39e5a241cad29 Mon Sep 17 00:00:00 2001 From: Meet Zaveri Date: Thu, 14 Dec 2017 22:26:08 +0530 Subject: [PATCH 172/202] Create Speech_synthesis.md Hey, I think this is the coolest one I found! Hope this snippet gets attraction --- snippets/Speech_synthesis.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 snippets/Speech_synthesis.md diff --git a/snippets/Speech_synthesis.md b/snippets/Speech_synthesis.md new file mode 100644 index 000000000..664decc73 --- /dev/null +++ b/snippets/Speech_synthesis.md @@ -0,0 +1,16 @@ +### Speech synthesis + +Currently The SpeechSynthesisUtterance interface of the Web Speech API represents a speech request. +It contains the content the speech service should read and information about how to read it (e.g. language, pitch and volume.) + +To know more - https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance + +``` +function speak (message) { + var msg = new SpeechSynthesisUtterance(message) + var voices = window.speechSynthesis.getVoices() + msg.voice = voices[0] + window.speechSynthesis.speak(msg) +} +speak('Hello, world') +``` From 984dc399d0de18ab5f91f7b8fc4b15f18798234d Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 19:02:15 +0200 Subject: [PATCH 173/202] Fixed build script to exclude untagged snippets --- README.md | 14 ++++++++++++-- scripts/builder.js | 4 ++-- tag_database | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 46fcf2e14..ba9eb3cfd 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ * [Current URL](#current-url) * [Element is visible in viewport](#element-is-visible-in-viewport) * [Get scroll position](#get-scroll-position) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Scroll to top](#scroll-to-top) ### Function @@ -528,7 +528,17 @@ const getScrollPos = (el = window) => [⬆ back to top](#table-of-contents) -undefined +### Redirect to URL + +Use `window.location.href` or `window.location.replace()` to redirect to `url`. +Pass a second argument to simulate a link click (`true` - default) or an HTTP redirect (`false`). + +```js +const redirect = (url, asLink = true) => + asLink ? window.location.href = url : window.location.replace(url); +// redirect('https://google.com') +``` + [⬆ back to top](#table-of-contents) ### Scroll to top diff --git a/scripts/builder.js b/scripts/builder.js index 6a15e53a7..ba345e67f 100644 --- a/scripts/builder.js +++ b/scripts/builder.js @@ -52,13 +52,13 @@ catch (err){ try { output += `${startPart+'\n'}`; - for(var tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].sort((a,b) => a.localeCompare(b))){ + for(var tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){ output +=`### ${capitalize(tag, true)}\n`; for(var taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) output += `* [${taggedSnippet[0][0].toUpperCase() + taggedSnippet[0].replace(/-/g,' ').slice(1)}](#${taggedSnippet[0].replace(/\(/g,'').replace(/\)/g,'').toLowerCase()})\n` output += '\n'; } - for(var tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].sort((a,b) => a.localeCompare(b))){ + for(var tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){ output +=`## ${capitalize(tag, true)}\n`; for(var taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) output += `\n${snippets[taggedSnippet[0]+'.md']+'\n[⬆ back to top](#table-of-contents)\n'}`; diff --git a/tag_database b/tag_database index 5619a0369..ef62da213 100644 --- a/tag_database +++ b/tag_database @@ -58,7 +58,7 @@ powerset:math promisify:function random-integer-in-range:utility random-number-in-range:utility -redirect-to-URL:browser +redirect-to-url:browser reverse-a-string:string RGB-to-hexadecimal:utility run-promises-in-series:function From 947275bf1a72f6ced296a5026071a86f581a1536 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 19:05:14 +0200 Subject: [PATCH 174/202] Tag and build README --- README.md | 2 +- tag_database | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e80f512da..190b57a2e 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ * [Current URL](#current-url) * [Element is visible in viewport](#element-is-visible-in-viewport) * [Get scroll position](#get-scroll-position) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Scroll to top](#scroll-to-top) ### Function diff --git a/tag_database b/tag_database index ef62da213..5619a0369 100644 --- a/tag_database +++ b/tag_database @@ -58,7 +58,7 @@ powerset:math promisify:function random-integer-in-range:utility random-number-in-range:utility -redirect-to-url:browser +redirect-to-URL:browser reverse-a-string:string RGB-to-hexadecimal:utility run-promises-in-series:function From 8de2749dfbe3262188ef288d1dcdae0bce530901 Mon Sep 17 00:00:00 2001 From: Meet Zaveri Date: Thu, 14 Dec 2017 22:39:24 +0530 Subject: [PATCH 175/202] Update Speech_synthesis.md used es6 approach acc. to contributing guidelines --- snippets/Speech_synthesis.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/snippets/Speech_synthesis.md b/snippets/Speech_synthesis.md index 664decc73..781f20d55 100644 --- a/snippets/Speech_synthesis.md +++ b/snippets/Speech_synthesis.md @@ -6,11 +6,11 @@ It contains the content the speech service should read and information about how To know more - https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance ``` -function speak (message) { +speak = message => { var msg = new SpeechSynthesisUtterance(message) var voices = window.speechSynthesis.getVoices() msg.voice = voices[0] window.speechSynthesis.speak(msg) -} -speak('Hello, world') + } +speak('Hello, World') ``` From 60d4736ff1d1c931f8ce8ee3cf170221c8e2e39f Mon Sep 17 00:00:00 2001 From: Meet Zaveri Date: Thu, 14 Dec 2017 22:43:10 +0530 Subject: [PATCH 176/202] Update Speech_synthesis.md --- snippets/Speech_synthesis.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/snippets/Speech_synthesis.md b/snippets/Speech_synthesis.md index 781f20d55..db1e084cd 100644 --- a/snippets/Speech_synthesis.md +++ b/snippets/Speech_synthesis.md @@ -7,8 +7,8 @@ To know more - https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisU ``` speak = message => { - var msg = new SpeechSynthesisUtterance(message) - var voices = window.speechSynthesis.getVoices() + const msg = new SpeechSynthesisUtterance(message) + const voices = window.speechSynthesis.getVoices() msg.voice = voices[0] window.speechSynthesis.speak(msg) } From 3e79c9071dbad1386992bef93a45635cc2b49dd2 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 19:24:17 +0200 Subject: [PATCH 177/202] Consistency for tools --- CONTRIBUTING.md | 3 +- package.json | 6 +- scripts/build-script.js | 79 ++++++++++++++++++++++ scripts/builder.js | 74 -------------------- scripts/{lintSnippet.js => lint-script.js} | 0 scripts/tag-script.js | 67 ++++++++++++++++++ scripts/tagger.js | 67 ------------------ 7 files changed, 151 insertions(+), 145 deletions(-) create mode 100644 scripts/build-script.js delete mode 100644 scripts/builder.js rename scripts/{lintSnippet.js => lint-script.js} (100%) create mode 100644 scripts/tag-script.js delete mode 100644 scripts/tagger.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d2bdbf7e1..4a1dc9e66 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,8 @@ Here's what you can do to help: - [Open issues](https://github.com/Chalarangelo/30-seconds-of-code/issues/new) for things you want to see added or modified. - Be part of the discussion by helping out with [existing issues](https://github.com/Chalarangelo/30-seconds-of-code/issues) or talking on our [gitter channel](https://gitter.im/30-seconds-of-code/Lobby). - Submit [pull requests](https://github.com/Chalarangelo/30-seconds-of-code/pulls) with snippets you have created (see below for guidelines). -- Fix typos in existing snippets or run `npm run lint "snippet-name.md"` on unlinted snippets (yes, this is something we actually want help with). +- Fix typos in existing snippets or run `npm run linter "snippet-name.md"` on unlinted snippets (yes, this is something we actually want help with). +- Tag untagged snippets by running `npm run tagger` and adding the appropriate tag next to the script name in `tag_database`. ### Snippet submission and Pull request guidelines diff --git a/package.json b/package.json index 2e12c8aac..4c6d5f82e 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,9 @@ "chalk": "^2.3.0" }, "scripts": { - "build-list": "node ./scripts/builder.js", - "lint": "node ./scripts/lintSnippet.js", - "tag": "node ./scripts/tagger.js", + "builder": "node ./scripts/build-script.js", + "linter": "node ./scripts/lint-script.js", + "tagger": "node ./scripts/tag-script.js", "start": "concurrently --kill-others \"nodemon -e js,md -i README.md -x \\\"npm run build-list\\\"\" \"live-server ./build\"" }, "repository": { diff --git a/scripts/build-script.js b/scripts/build-script.js new file mode 100644 index 000000000..05514ae78 --- /dev/null +++ b/scripts/build-script.js @@ -0,0 +1,79 @@ +/* + This is the builder script that generates the README file. + Run using `npm run builder`. +*/ +// Load modules +const fs = require('fs-extra'), path = require('path'), chalk = require('chalk'); +// Set variables for paths +const snippetsPath = './snippets', staticPartsPath = './static-parts'; +// Set variables for script +let snippets = {}, startPart = '', endPart = '', output = '', tagDbData = {}; +// Load helper functions (these are from existing snippets in 30 seconds of code!) +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); +const capitalize = (str, lowerRest = false) => str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); +// Start the timer of the script +console.time('Builder'); +// Synchronously read all snippets and sort them as necessary (case-insensitive) +try { + let snippetFilenames = fs.readdirSync(snippetsPath); + snippetFilenames.sort((a, b) => { + a = a.toLowerCase(); + b = b.toLowerCase(); + if (a < b) return -1; + if (a > b) return 1; + return 0; + }); + // Store the data read from each snippet in the appropriate object + for(let snippet of snippetFilenames) snippets[snippet] = fs.readFileSync(path.join(snippetsPath,snippet),'utf8'); +} +catch (err){ // Handle errors (hopefully not!) + console.log(`${chalk.red('ERROR!')} During snippet loading: ${err}`); + process.exit(1); +} +// Load static parts for the README file +try { + startPart = fs.readFileSync(path.join(staticPartsPath,'README-start.md'),'utf8'); + endPart = fs.readFileSync(path.join(staticPartsPath,'README-end.md'),'utf8'); +} +catch (err){ // Handle errors (hopefully not!) + console.log(`${chalk.red('ERROR!')} During static part loading: ${err}`); + process.exit(1); +} +// Load tag data from the database +try { + tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').slice(0,-1).map(v => v.split(':').slice(0,2))); +} +catch (err){ // Handle errors (hopefully not!) + console.log(`${chalk.red('ERROR!')} During tag database loading: ${err}`); + process.exit(1); +} +// Create the output for the README file +try { + // Add the start static part + output += `${startPart+'\n'}`; + // Loop over tags and snippets to create the table of contents + for(let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){ + output +=`### ${capitalize(tag, true)}\n`; + for(let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) + output += `* [${taggedSnippet[0][0].toUpperCase() + taggedSnippet[0].replace(/-/g,' ').slice(1)}](#${taggedSnippet[0].replace(/\(/g,'').replace(/\)/g,'').toLowerCase()})\n` + output += '\n'; + } + // Loop over tags and snippets to create the list of snippets + for(let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){ + output +=`## ${capitalize(tag, true)}\n`; + for(let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) + output += `\n${snippets[taggedSnippet[0]+'.md']+'\n[⬆ back to top](#table-of-contents)\n'}`; + } + // Add the ending static part + output += `\n${endPart+'\n'}`; + // Write to the README file + fs.writeFileSync('README.md', output); +} +catch (err){ // Handle errors (hopefully not!) + console.log(`${chalk.red('ERROR!')} During README generation: ${err}`); + process.exit(1); +} +// Log a success message +console.log(`${chalk.green('SUCCESS!')} README file generated!`); +// Log the time taken +console.timeEnd('Builder'); diff --git a/scripts/builder.js b/scripts/builder.js deleted file mode 100644 index ba345e67f..000000000 --- a/scripts/builder.js +++ /dev/null @@ -1,74 +0,0 @@ -var fs = require('fs-extra'); -var path = require('path'); - -var snippetsPath = './snippets'; -var staticPartsPath = './static-parts'; - -var snippets = {}, startPart = '', endPart = '', output = '', tagDbData = {}; - -const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); -const capitalize = (str, lowerRest = false) => str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); - -console.time('Builder'); - -try { - var snippetFilenames = fs.readdirSync(snippetsPath); - snippetFilenames.sort((a, b) => { - a = a.toLowerCase(); - b = b.toLowerCase(); - if (a < b) { - return -1; - } - if (a > b) { - return 1; - } - return 0; - }); - for(var snippet of snippetFilenames){ - snippets[snippet] = fs.readFileSync(path.join(snippetsPath,snippet),'utf8'); - } -} -catch (err){ - console.log('Error during snippet loading: '+err); - process.exit(1); -} - -try { - startPart = fs.readFileSync(path.join(staticPartsPath,'README-start.md'),'utf8'); - endPart = fs.readFileSync(path.join(staticPartsPath,'README-end.md'),'utf8'); -} -catch (err){ - console.log('Error during static part loading: '+err); - process.exit(1); -} - -try { - tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').slice(0,-1).map(v => v.split(':').slice(0,2))); -} -catch (err){ - console.log('Error during tag database loading: '+err); - process.exit(1); -} - -try { - output += `${startPart+'\n'}`; - for(var tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){ - output +=`### ${capitalize(tag, true)}\n`; - for(var taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) - output += `* [${taggedSnippet[0][0].toUpperCase() + taggedSnippet[0].replace(/-/g,' ').slice(1)}](#${taggedSnippet[0].replace(/\(/g,'').replace(/\)/g,'').toLowerCase()})\n` - output += '\n'; - } - for(var tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){ - output +=`## ${capitalize(tag, true)}\n`; - for(var taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) - output += `\n${snippets[taggedSnippet[0]+'.md']+'\n[⬆ back to top](#table-of-contents)\n'}`; - } - output += `\n${endPart+'\n'}`; - fs.writeFileSync('README.md', output); -} -catch (err){ - console.log('Error during README generation: '+err); - process.exit(1); -} - -console.timeEnd('Builder'); diff --git a/scripts/lintSnippet.js b/scripts/lint-script.js similarity index 100% rename from scripts/lintSnippet.js rename to scripts/lint-script.js diff --git a/scripts/tag-script.js b/scripts/tag-script.js new file mode 100644 index 000000000..8537b3009 --- /dev/null +++ b/scripts/tag-script.js @@ -0,0 +1,67 @@ +/* + This is the tagger script that updates the tag_databse file and logs stats for snippet tags. + Run using `npm run tagger`. +*/ +// Load modules +const fs = require('fs-extra'), path = require('path'), chalk = require('chalk'); +// Set variables for paths +const snippetsPath = './snippets'; +// Set variables for script +let snippets = {}, output = '', tagDbData = {}, missingTags = 0, tagDbStats = {}; +// Load helper functions (these are from existing snippets in 30 seconds of code!) +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); +const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); +// Start the timer of the script +console.time('Tagger'); +// Synchronously read all snippets and sort them as necessary (case-insensitive) +try { + let snippetFilenames = fs.readdirSync(snippetsPath); + snippetFilenames.sort((a, b) => { + a = a.toLowerCase(); + b = b.toLowerCase(); + if (a < b) return -1; + if (a > b) return 1; + return 0; + }); + // Store the data read from each snippet in the appropriate object + for(let snippet of snippetFilenames) snippets[snippet] = fs.readFileSync(path.join(snippetsPath,snippet),'utf8'); +} +catch (err){ // Handle errors (hopefully not!) + console.log(`${chalk.red('ERROR!')} During snippet loading: ${err}`); + process.exit(1); +} +// Load tag data from the database +try { + tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').slice(0,-1).map(v => v.split(':').slice(0,2))); + tagDbStats = Object.entries(tagDbData).sort((a,b) => a[1].localeCompare(b[1])).reduce((acc, val) => {acc.hasOwnProperty(val[1]) ? acc[val[1]]++ : acc[val[1]] = 1; return acc;}, {}); +} +catch (err){ // Handle errors (hopefully not!) + console.log(`${chalk.red('ERROR!')} During tag database loading: ${err}`); + process.exit(1); +} +// Update the listing of snippets in tag_database and log the statistics, along with missing scripts +try { + for(let snippet of Object.entries(snippets)) + if(tagDbData.hasOwnProperty(snippet[0].slice(0,-3)) && tagDbData[snippet[0].slice(0,-3)].trim()) + output += `${snippet[0].slice(0,-3)}:${tagDbData[snippet[0].slice(0,-3)].trim()}\n`; + else { + output += `${snippet[0].slice(0,-3)}:\n`; + missingTags++; + console.log(`${chalk.yellow('Tag missing:')} ${snippet[0].slice(0,-3)}`); + } + // Write to tag_database + fs.writeFileSync('tag_database', output); +} +catch (err){ // Handle errors (hopefully not!) + console.log(`${chalk.red('ERROR!')} During tag_database generation: ${err}`); + process.exit(1); +} +// Log statistics for the tag_database file +console.log(`\n${chalk.bgWhite(chalk.black('=== TAG STATS ==='))}`) +for(let tagData of Object.entries(tagDbStats).filter(v => v[0] !== 'undefined')) + console.log(`${chalk.green(tagData[0])}: ${tagData[1]} snippets`); +console.log(`${chalk.blue('Untagged snippets:')} ${missingTags}\n`); +// Log a success message +console.log(`${chalk.green('SUCCESS!')} tag_database file updated!`); +// Log the time taken +console.timeEnd('Tagger'); diff --git a/scripts/tagger.js b/scripts/tagger.js deleted file mode 100644 index ecebce50f..000000000 --- a/scripts/tagger.js +++ /dev/null @@ -1,67 +0,0 @@ -var fs = require('fs-extra'); -var path = require('path'); -var chalk = require('chalk'); - -var snippetsPath = './snippets'; - -var snippets = {}, output = '', tagDbData = {}, missingTags = 0, tagDbStats = {}; - -const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); -const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); - - -console.time('Tagger'); - -try { - var snippetFilenames = fs.readdirSync(snippetsPath); - snippetFilenames.sort((a, b) => { - a = a.toLowerCase(); - b = b.toLowerCase(); - if (a < b) { - return -1; - } - if (a > b) { - return 1; - } - return 0; - }); - for(var snippet of snippetFilenames){ - snippets[snippet] = fs.readFileSync(path.join(snippetsPath,snippet),'utf8'); - } -} -catch (err){ - console.log('Error during snippet loading: '+err); - process.exit(1); -} - -try { - tagDbData = objectFromPairs(fs.readFileSync('tag_database','utf8').split('\n').slice(0,-1).map(v => v.split(':').slice(0,2))); - tagDbStats = Object.entries(tagDbData).sort((a,b) => a[1].localeCompare(b[1])).reduce((acc, val) => {acc.hasOwnProperty(val[1]) ? acc[val[1]]++ : acc[val[1]] = 1; return acc;}, {}); -} -catch (err){ - console.log('Error during tag database loading: '+err); - process.exit(1); -} - -try { - for(var snippet of Object.entries(snippets)) - if(tagDbData.hasOwnProperty(snippet[0].slice(0,-3)) && tagDbData[snippet[0].slice(0,-3)].trim()) - output += `${snippet[0].slice(0,-3)}:${tagDbData[snippet[0].slice(0,-3)].trim()}\n`; - else { - output += `${snippet[0].slice(0,-3)}:\n`; - missingTags++; - console.log(`${chalk.red('Tag missing:')} ${snippet[0].slice(0,-3)}`); - } - fs.writeFileSync('tag_database', output); -} -catch (err){ - console.log('Error during README generation: '+err); - process.exit(1); -} -console.log(`\n=== TAG STATS ===`) -for(var tagData of Object.entries(tagDbStats).filter(v => v[0] !== 'undefined')){ - console.log(`${chalk.green(tagData[0])}: ${tagData[1]} snippets`); -} -console.log(`${chalk.blue('Untagged snippets:')} ${missingTags}\n`); - -console.timeEnd('Tagger'); From d2917bf1200c72eb7877c66de090a0fc1f2ee707 Mon Sep 17 00:00:00 2001 From: Meet Zaveri Date: Thu, 14 Dec 2017 23:02:18 +0530 Subject: [PATCH 178/202] Update Speech_synthesis.md --- snippets/Speech_synthesis.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/snippets/Speech_synthesis.md b/snippets/Speech_synthesis.md index db1e084cd..022601472 100644 --- a/snippets/Speech_synthesis.md +++ b/snippets/Speech_synthesis.md @@ -6,11 +6,10 @@ It contains the content the speech service should read and information about how To know more - https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance ``` -speak = message => { - const msg = new SpeechSynthesisUtterance(message) - const voices = window.speechSynthesis.getVoices() - msg.voice = voices[0] - window.speechSynthesis.speak(msg) - } +const speak = message => { + const msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +} speak('Hello, World') ``` From 94c1923ee7f0ae052fd0001e6db7e21489f7a7e0 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 19:38:11 +0200 Subject: [PATCH 179/202] Updated tools, proper linting, build README --- CONTRIBUTING.md | 2 +- README.md | 34 +++++------ scripts/lint-script.js | 65 +++++++++++++--------- snippets/array-difference.md | 2 +- snippets/array-intersection.md | 2 +- snippets/array-union.md | 2 +- snippets/collatz-algorithm.md | 2 +- snippets/drop-elements-in-array.md | 6 +- snippets/element-is-visible-in-viewport.md | 2 +- snippets/fill-array.md | 4 +- snippets/flatten-array-up-to-depth.md | 4 +- snippets/ordinal-suffix-of-number.md | 8 +-- snippets/standard-deviation.md | 2 +- 13 files changed, 74 insertions(+), 61 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4a1dc9e66..618a99b1a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,8 +7,8 @@ Here's what you can do to help: - [Open issues](https://github.com/Chalarangelo/30-seconds-of-code/issues/new) for things you want to see added or modified. - Be part of the discussion by helping out with [existing issues](https://github.com/Chalarangelo/30-seconds-of-code/issues) or talking on our [gitter channel](https://gitter.im/30-seconds-of-code/Lobby). - Submit [pull requests](https://github.com/Chalarangelo/30-seconds-of-code/pulls) with snippets you have created (see below for guidelines). -- Fix typos in existing snippets or run `npm run linter "snippet-name.md"` on unlinted snippets (yes, this is something we actually want help with). - Tag untagged snippets by running `npm run tagger` and adding the appropriate tag next to the script name in `tag_database`. +- Fix typos in existing snippets or run `npm run linter` to lint unlinted snippets (yes, this is something we actually want help with, as this can take quite a while to run). ### Snippet submission and Pull request guidelines diff --git a/README.md b/README.md index 190b57a2e..ead95c6f1 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ const arrayConcat = (arr, ...args) => arr.concat(...args); Create a `Set` from `b`, then use `Array.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)); } +const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); }; // difference([1,2,3], [1,2]) -> [3] ``` @@ -133,7 +133,7 @@ const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has Create a `Set` from `b`, then use `Array.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)); } +const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); }; // intersection([1,2,3], [4,3,2]) -> [2,3] ``` @@ -144,7 +144,7 @@ const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.ha 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])) +const union = (a, b) => Array.from(new Set([...a, ...b])); // union([1,2,3], [4,3,2]) -> [1,2,3,4] ``` @@ -216,10 +216,10 @@ Loop through the array, using `Array.shift()` to drop the first element of the a Returns the remaining elements. ```js -const dropElements = (arr,func) => { - while(arr.length > 0 && !func(arr[0])) arr.shift(); +const dropElements = (arr, func) => { + while (arr.length > 0 && !func(arr[0])) arr.shift(); return arr; -} +}; // dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4] ``` @@ -231,8 +231,8 @@ Use `Array.map()` to map values between `start` (inclusive) and `end` (exclusive Omit `start` to start at the first element and/or `end` to finish at the last. ```js -const fillArray = (arr, value, start = 0, end = arr.length) => - arr.map((v,i) => i>=start && i + arr.map((v, i) => i >= start && i < end ? value : v); // fillArray([1,2,3,4],'8',1,3) -> [1,'8','8',4] ``` @@ -258,8 +258,8 @@ Omit the second element, `depth` to flatten only to a depth of `1` (single flatt ```js const flattenDepth = (arr, depth = 1) => - depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth (v, depth-1) : v), []) - : arr.reduce((a,v) => a.concat(v),[]); + depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), []) + : arr.reduce((a, v) => a.concat(v), []); // flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5] ``` @@ -506,7 +506,7 @@ const elementIsVisibleInViewport = (el, partiallyVisible = false) => { ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; -} +}; // e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10} // elementIsVisibleInViewport(el) -> false (not fully visible) // elementIsVisibleInViewport(el, true) -> true (partially visible) @@ -664,7 +664,7 @@ async function sleepyWork() { If `n` is even, return `n/2`. Otherwise return `3n+1`. ```js -const collatz = n => (n % 2 == 0) ? (n/2) : (3*n+1); +const collatz = n => (n % 2 == 0) ? (n / 2) : (3 * n + 1); // collatz(8) --> 4 // collatz(5) --> 16 ``` @@ -795,7 +795,7 @@ const standardDeviation = (arr, usePopulation = false) => { arr.reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) .reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1)) ); - } +}; // standardDeviation([10,2,38,23,38,23,21]) -> 13.284434142114991 (sample) // standardDeviation([10,2,38,23,38,23,21], true) -> 12.29899614287479 (population) ``` @@ -1041,10 +1041,10 @@ If digit is found in teens pattern, use teens ordinal. ```js const toOrdinalSuffix = num => { const int = parseInt(num), digits = [(int % 10), (int % 100)], - ordinals = ["st", "nd", "rd", "th"], oPattern = [1,2,3,4], - tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] - return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; -} + ordinals = ['st', 'nd', 'rd', 'th'], oPattern = [1, 2, 3, 4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0] - 1] : int + ordinals[3]; +}; // toOrdinalSuffix("123") -> "123rd" ``` diff --git a/scripts/lint-script.js b/scripts/lint-script.js index a53686ee5..3aba12d27 100644 --- a/scripts/lint-script.js +++ b/scripts/lint-script.js @@ -1,31 +1,44 @@ -var fs = require('fs-extra'); -var cp = require('child_process'); -var path = require('path'); - +/* + This is the linter script that lints snippets. + Run using `npm run linter`. +*/ +// Load modules +const fs = require('fs-extra'), cp = require('child_process'), path = require('path'); +// Set variables for paths var snippetsPath = './snippets'; -var snippetFilename = ''; - -console.time('Linter'); - -if(process.argv.length < 3){ - console.log('Please specify the filename of a snippet to be linted.'); - console.log('Example usage: npm run lint "snippet-file.md"'); - process.exit(0); -} -else { - snippetFilename = process.argv[2]; - let snippetData = fs.readFileSync(path.join(snippetsPath,snippetFilename),'utf8'); - try { +// Read files, lint each one individually and update +try { + let snippetFilenames = fs.readdirSync(snippetsPath); + snippetFilenames.sort((a, b) => { + a = a.toLowerCase(); + b = b.toLowerCase(); + if (a < b) return -1; + if (a > b) return 1; + return 0; + }); + // Read each file, get its code, write it to a temporary file, pass it through + // semistandard, get the output from the file, update the original file. + for(let snippet of snippetFilenames){ + // Start a timer for the file + console.time(`Linter (${snippet})`); + // Synchronously read data from the snippet, get the code, write it to a temporary file + let snippetData = fs.readFileSync(path.join(snippetsPath,snippet),'utf8'); let originalCode = snippetData.slice(snippetData.indexOf('```js')+5,snippetData.lastIndexOf('```')); - fs.writeFileSync('currentSnippet.js',`${originalCode}`); - cp.exec('semistandard "currentSnippet.js" --fix',{},(error, stdOut, stdErr) => { - let lintedCode = fs.readFileSync('currentSnippet.js','utf8'); - fs.writeFile(path.join(snippetsPath,snippetFilename), `${snippetData.slice(0, snippetData.indexOf('```js')+5)+lintedCode+'```\n'}`); - console.timeEnd('Linter'); + fs.writeFileSync(`${snippet}.temp.js`,`${originalCode}`); + // Run semistandard asynchronously (only way this manages to run), get linted code + // and write back to the original snippet file. Remove temporary file + cp.exec(`semistandard "${snippet}.temp.js" --fix`,{},(error, stdOut, stdErr) => { + let lintedCode = fs.readFileSync(`${snippet}.temp.js`,'utf8'); + fs.writeFile(path.join(snippetsPath,snippet), `${snippetData.slice(0, snippetData.indexOf('```js')+5)+lintedCode+'```\n'}`); + fs.unlink(`${snippet}.temp.js`); + // Log a success message + console.log(`${chalk.red('SUCCESS!')} Linted snippet: ${snippet}`); + // Log the time taken for the file + console.timeEnd(`Linter (${snippet})`); }); } - catch (err){ - console.log('Error during snippet loading: '+err); - process.exit(1); - } +} +catch (err){ // Handle errors (hopefully not!) + console.log(`${chalk.red('ERROR!')} During linting: ${err}`); + process.exit(1); } diff --git a/snippets/array-difference.md b/snippets/array-difference.md index 46469b1d6..208cb811e 100644 --- a/snippets/array-difference.md +++ b/snippets/array-difference.md @@ -3,6 +3,6 @@ Create a `Set` from `b`, then use `Array.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)); } +const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); }; // difference([1,2,3], [1,2]) -> [3] ``` diff --git a/snippets/array-intersection.md b/snippets/array-intersection.md index 87c42378b..780ab1d85 100644 --- a/snippets/array-intersection.md +++ b/snippets/array-intersection.md @@ -3,6 +3,6 @@ Create a `Set` from `b`, then use `Array.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)); } +const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); }; // intersection([1,2,3], [4,3,2]) -> [2,3] ``` diff --git a/snippets/array-union.md b/snippets/array-union.md index b417dcce7..6224227d1 100644 --- a/snippets/array-union.md +++ b/snippets/array-union.md @@ -3,6 +3,6 @@ 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])) +const union = (a, b) => Array.from(new Set([...a, ...b])); // union([1,2,3], [4,3,2]) -> [1,2,3,4] ``` diff --git a/snippets/collatz-algorithm.md b/snippets/collatz-algorithm.md index 730bdd9e3..61614e5e0 100644 --- a/snippets/collatz-algorithm.md +++ b/snippets/collatz-algorithm.md @@ -3,7 +3,7 @@ If `n` is even, return `n/2`. Otherwise return `3n+1`. ```js -const collatz = n => (n % 2 == 0) ? (n/2) : (3*n+1); +const collatz = n => (n % 2 == 0) ? (n / 2) : (3 * n + 1); // collatz(8) --> 4 // collatz(5) --> 16 ``` diff --git a/snippets/drop-elements-in-array.md b/snippets/drop-elements-in-array.md index 0ad2ab5e9..236c5ab56 100644 --- a/snippets/drop-elements-in-array.md +++ b/snippets/drop-elements-in-array.md @@ -4,9 +4,9 @@ Loop through the array, using `Array.shift()` to drop the first element of the a Returns the remaining elements. ```js -const dropElements = (arr,func) => { - while(arr.length > 0 && !func(arr[0])) arr.shift(); +const dropElements = (arr, func) => { + while (arr.length > 0 && !func(arr[0])) arr.shift(); return arr; -} +}; // dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4] ``` diff --git a/snippets/element-is-visible-in-viewport.md b/snippets/element-is-visible-in-viewport.md index 70ff83134..514aea5e6 100644 --- a/snippets/element-is-visible-in-viewport.md +++ b/snippets/element-is-visible-in-viewport.md @@ -12,7 +12,7 @@ const elementIsVisibleInViewport = (el, partiallyVisible = false) => { ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; -} +}; // e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10} // elementIsVisibleInViewport(el) -> false (not fully visible) // elementIsVisibleInViewport(el, true) -> true (partially visible) diff --git a/snippets/fill-array.md b/snippets/fill-array.md index a08c4362e..a5da15483 100644 --- a/snippets/fill-array.md +++ b/snippets/fill-array.md @@ -4,7 +4,7 @@ Use `Array.map()` to map values between `start` (inclusive) and `end` (exclusive Omit `start` to start at the first element and/or `end` to finish at the last. ```js -const fillArray = (arr, value, start = 0, end = arr.length) => - arr.map((v,i) => i>=start && i + arr.map((v, i) => i >= start && i < end ? value : v); // fillArray([1,2,3,4],'8',1,3) -> [1,'8','8',4] ``` diff --git a/snippets/flatten-array-up-to-depth.md b/snippets/flatten-array-up-to-depth.md index d28af98fb..b6e3805b6 100644 --- a/snippets/flatten-array-up-to-depth.md +++ b/snippets/flatten-array-up-to-depth.md @@ -7,7 +7,7 @@ Omit the second element, `depth` to flatten only to a depth of `1` (single flatt ```js const flattenDepth = (arr, depth = 1) => - depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth (v, depth-1) : v), []) - : arr.reduce((a,v) => a.concat(v),[]); + depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), []) + : arr.reduce((a, v) => a.concat(v), []); // flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5] ``` diff --git a/snippets/ordinal-suffix-of-number.md b/snippets/ordinal-suffix-of-number.md index 4e849eff7..d3166928b 100644 --- a/snippets/ordinal-suffix-of-number.md +++ b/snippets/ordinal-suffix-of-number.md @@ -7,9 +7,9 @@ If digit is found in teens pattern, use teens ordinal. ```js const toOrdinalSuffix = num => { const int = parseInt(num), digits = [(int % 10), (int % 100)], - ordinals = ["st", "nd", "rd", "th"], oPattern = [1,2,3,4], - tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] - return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; -} + ordinals = ['st', 'nd', 'rd', 'th'], oPattern = [1, 2, 3, 4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0] - 1] : int + ordinals[3]; +}; // toOrdinalSuffix("123") -> "123rd" ``` diff --git a/snippets/standard-deviation.md b/snippets/standard-deviation.md index e559972bb..5819579ad 100644 --- a/snippets/standard-deviation.md +++ b/snippets/standard-deviation.md @@ -11,7 +11,7 @@ const standardDeviation = (arr, usePopulation = false) => { arr.reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) .reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1)) ); - } +}; // standardDeviation([10,2,38,23,38,23,21]) -> 13.284434142114991 (sample) // standardDeviation([10,2,38,23,38,23,21], true) -> 12.29899614287479 (population) ``` From b4f7d8cba7f03e5d61eb77c29bc23f7ffd2aae5a Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 20:13:16 +0200 Subject: [PATCH 180/202] Build README --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ead95c6f1..5777cbc88 100644 --- a/README.md +++ b/README.md @@ -585,13 +585,10 @@ Otherwise return a curried function `f` that expects the rest of the arguments. If you want to curry a function that accepts a variable number of arguments (a variadic function, e.g. `Math.min()`), you can optionally pass the number of arguments to the second parameter `arity`. ```js -const curry = (f, arity = f.length, next) => - (next = prevArgs => - nextArg => { - const args = [ ...prevArgs, nextArg ]; - return args.length >= arity ? f(...args) : next(args); - } - )([]); +const curry = (fn, arity = fn.length, ...args) => + arity <= args.length + ? fn(...args) + : curry.bind(null, fn, arity, ...args) // curry(Math.pow)(2)(10) -> 1024 // curry(Math.min, 3)(10)(50)(2) -> 2 ``` From 08f0637de20087e739cc991a4714c55dee6c2291 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 20:20:37 +0200 Subject: [PATCH 181/202] Resolve #111 --- snippets/is-array.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/is-array.md b/snippets/is-array.md index 7652f74c9..939cb086d 100644 --- a/snippets/is-array.md +++ b/snippets/is-array.md @@ -3,7 +3,7 @@ Use `Array.isArray()` to check if a value is classified as an array. ```js -const isArray = val => val && Array.isArray(val); +const isArray = val => !!val && Array.isArray(val); // isArray(null) -> false // isArray([1]) -> true ``` From be0a582417abf707a4d5d0ce5db59be4d2de3264 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 20:21:26 +0200 Subject: [PATCH 182/202] Build README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5777cbc88..b47ab9fce 100644 --- a/README.md +++ b/README.md @@ -946,7 +946,7 @@ const getType = v => Use `Array.isArray()` to check if a value is classified as an array. ```js -const isArray = val => val && Array.isArray(val); +const isArray = val => !!val && Array.isArray(val); // isArray(null) -> false // isArray([1]) -> true ``` From 4648bf00c623467fce3a826a707515c7d2eb838e Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 20:24:12 +0200 Subject: [PATCH 183/202] Update get-days-difference-between-dates.md --- snippets/get-days-difference-between-dates.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/snippets/get-days-difference-between-dates.md b/snippets/get-days-difference-between-dates.md index 152cd7167..d97463adb 100644 --- a/snippets/get-days-difference-between-dates.md +++ b/snippets/get-days-difference-between-dates.md @@ -1,6 +1,6 @@ -### Get Days Difference Between Dates +### Get days difference between dates -Returns the number of days between two Dates. +Calculate the difference (in days) between to `Date` objects. ```js const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24); From e088653e3eaeca2f2ca2da0cd58a9e1da2c7d760 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 20:26:20 +0200 Subject: [PATCH 184/202] Tag and build --- README.md | 15 +++++++++++++++ tag_database | 1 + 2 files changed, 16 insertions(+) diff --git a/README.md b/README.md index b47ab9fce..6c3c68b31 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,9 @@ * [Redirect to URL](#redirect-to-url) * [Scroll to top](#scroll-to-top) +### Date +* [Get days difference between dates](#get-days-difference-between-dates) + ### Function * [Chain asynchronous functions](#chain-asynchronous-functions) * [Curry](#curry) @@ -557,6 +560,18 @@ const scrollToTop = _ => { // scrollToTop() ``` +[⬆ back to top](#table-of-contents) +## Date + +### Get days difference between dates + +Calculate the difference (in days) between to `Date` objects. + +```js +const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24); +//getDaysDiffBetweenDates(new Date("2017-12-13"), new Date("2017-12-22")) -> 9 +``` + [⬆ back to top](#table-of-contents) ## Function diff --git a/tag_database b/tag_database index 5619a0369..a8d4fa8dd 100644 --- a/tag_database +++ b/tag_database @@ -28,6 +28,7 @@ fill-array:array filter-out-non-unique-values-in-an-array:array flatten-array-up-to-depth:array flatten-array:array +get-days-difference-between-dates:date get-max-value-from-array:array get-min-value-from-array:array get-native-type-of-value:utility From c5ccd1befb1d0e67f3e7fbb1bf6ee0bfcacdb4ee Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 20:47:23 +0200 Subject: [PATCH 185/202] Update and rename Speech_synthesis.md to speech_synthesis-(experimental).md --- snippets/Speech_synthesis.md | 15 --------------- snippets/speech_synthesis-(experimental).md | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 15 deletions(-) delete mode 100644 snippets/Speech_synthesis.md create mode 100644 snippets/speech_synthesis-(experimental).md diff --git a/snippets/Speech_synthesis.md b/snippets/Speech_synthesis.md deleted file mode 100644 index 022601472..000000000 --- a/snippets/Speech_synthesis.md +++ /dev/null @@ -1,15 +0,0 @@ -### Speech synthesis - -Currently The SpeechSynthesisUtterance interface of the Web Speech API represents a speech request. -It contains the content the speech service should read and information about how to read it (e.g. language, pitch and volume.) - -To know more - https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance - -``` -const speak = message => { - const msg = new SpeechSynthesisUtterance(message); - msg.voice = window.speechSynthesis.getVoices()[0]; - window.speechSynthesis.speak(msg); -} -speak('Hello, World') -``` diff --git a/snippets/speech_synthesis-(experimental).md b/snippets/speech_synthesis-(experimental).md new file mode 100644 index 000000000..74cdcf161 --- /dev/null +++ b/snippets/speech_synthesis-(experimental).md @@ -0,0 +1,15 @@ +### Speech synthesis (experimental) + +Use `SpeechSynthesisUtterance.voice` and `indow.speechSynthesis.getVoices()` to convert a message to speech. +Use `window.speechSynthesis.speak()` to play the message. + +Learn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance). + +```js +const speak = message => { + const msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +} +// speak('Hello, World') -> plays the message +``` From ec33cf6c19716dee07ad7a9c290c6b44c64e23c7 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 20:49:06 +0200 Subject: [PATCH 186/202] Tag and build --- README.md | 22 ++++++++++++++++++++++ tag_database | 1 + 2 files changed, 23 insertions(+) diff --git a/README.md b/README.md index 6c3c68b31..3f3da1a6b 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,9 @@ * [Powerset](#powerset) * [Standard deviation](#standard-deviation) +### Media +* [Speech_synthesis (experimental)](#speech_synthesis-experimental) + ### Object * [Object from key value pairs](#object-from-key-value-pairs) * [Object to key value pairs](#object-to-key-value-pairs) @@ -812,6 +815,25 @@ const standardDeviation = (arr, usePopulation = false) => { // standardDeviation([10,2,38,23,38,23,21], true) -> 12.29899614287479 (population) ``` +[⬆ back to top](#table-of-contents) +## Media + +### Speech synthesis (experimental) + +Use `SpeechSynthesisUtterance.voice` and `indow.speechSynthesis.getVoices()` to convert a message to speech. +Use `window.speechSynthesis.speak()` to play the message. + +Learn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance). + +```js +const speak = message => { + const msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +} +// speak('Hello, World') -> plays the message +``` + [⬆ back to top](#table-of-contents) ## Object diff --git a/tag_database b/tag_database index a8d4fa8dd..01c21bce9 100644 --- a/tag_database +++ b/tag_database @@ -68,6 +68,7 @@ shuffle-array:array similarity-between-arrays:array sleep:function sort-characters-in-string-(alphabetical):string +speech_synthesis-(experimental):media standard-deviation:math sum-of-array-of-numbers:array swap-values-of-two-variables:utility From e7254345aa7e5b02ed09861d1a77fbbe6a080486 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 20:52:07 +0200 Subject: [PATCH 187/202] Lint and build --- .gitignore | 2 +- README.md | 6 +++--- scripts/lint-script.js | 4 ++-- snippets/curry.md | 2 +- snippets/get-days-difference-between-dates.md | 2 +- snippets/speech_synthesis-(experimental).md | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index bc23f6a88..9fe5cb489 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ node_modules/ - currentSnippet\.js +*.md.temp.js diff --git a/README.md b/README.md index 3f3da1a6b..142e14a79 100644 --- a/README.md +++ b/README.md @@ -572,7 +572,7 @@ Calculate the difference (in days) between to `Date` objects. ```js const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24); -//getDaysDiffBetweenDates(new Date("2017-12-13"), new Date("2017-12-22")) -> 9 +// getDaysDiffBetweenDates(new Date("2017-12-13"), new Date("2017-12-22")) -> 9 ``` [⬆ back to top](#table-of-contents) @@ -606,7 +606,7 @@ If you want to curry a function that accepts a variable number of arguments (a v const curry = (fn, arity = fn.length, ...args) => arity <= args.length ? fn(...args) - : curry.bind(null, fn, arity, ...args) + : curry.bind(null, fn, arity, ...args); // curry(Math.pow)(2)(10) -> 1024 // curry(Math.min, 3)(10)(50)(2) -> 2 ``` @@ -830,7 +830,7 @@ const speak = message => { const msg = new SpeechSynthesisUtterance(message); msg.voice = window.speechSynthesis.getVoices()[0]; window.speechSynthesis.speak(msg); -} +}; // speak('Hello, World') -> plays the message ``` diff --git a/scripts/lint-script.js b/scripts/lint-script.js index 3aba12d27..5d6d8721e 100644 --- a/scripts/lint-script.js +++ b/scripts/lint-script.js @@ -3,7 +3,7 @@ Run using `npm run linter`. */ // Load modules -const fs = require('fs-extra'), cp = require('child_process'), path = require('path'); +const fs = require('fs-extra'), cp = require('child_process'), path = require('path'), chalk = require('chalk'); // Set variables for paths var snippetsPath = './snippets'; // Read files, lint each one individually and update @@ -32,7 +32,7 @@ try { fs.writeFile(path.join(snippetsPath,snippet), `${snippetData.slice(0, snippetData.indexOf('```js')+5)+lintedCode+'```\n'}`); fs.unlink(`${snippet}.temp.js`); // Log a success message - console.log(`${chalk.red('SUCCESS!')} Linted snippet: ${snippet}`); + console.log(`${chalk.green('SUCCESS!')} Linted snippet: ${snippet}`); // Log the time taken for the file console.timeEnd(`Linter (${snippet})`); }); diff --git a/snippets/curry.md b/snippets/curry.md index b47492721..bbee4086c 100644 --- a/snippets/curry.md +++ b/snippets/curry.md @@ -9,7 +9,7 @@ If you want to curry a function that accepts a variable number of arguments (a v const curry = (fn, arity = fn.length, ...args) => arity <= args.length ? fn(...args) - : curry.bind(null, fn, arity, ...args) + : curry.bind(null, fn, arity, ...args); // curry(Math.pow)(2)(10) -> 1024 // curry(Math.min, 3)(10)(50)(2) -> 2 ``` diff --git a/snippets/get-days-difference-between-dates.md b/snippets/get-days-difference-between-dates.md index d97463adb..ae93ce79d 100644 --- a/snippets/get-days-difference-between-dates.md +++ b/snippets/get-days-difference-between-dates.md @@ -4,5 +4,5 @@ Calculate the difference (in days) between to `Date` objects. ```js const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24); -//getDaysDiffBetweenDates(new Date("2017-12-13"), new Date("2017-12-22")) -> 9 +// getDaysDiffBetweenDates(new Date("2017-12-13"), new Date("2017-12-22")) -> 9 ``` diff --git a/snippets/speech_synthesis-(experimental).md b/snippets/speech_synthesis-(experimental).md index 74cdcf161..c9e6a288c 100644 --- a/snippets/speech_synthesis-(experimental).md +++ b/snippets/speech_synthesis-(experimental).md @@ -10,6 +10,6 @@ const speak = message => { const msg = new SpeechSynthesisUtterance(message); msg.voice = window.speechSynthesis.getVoices()[0]; window.speechSynthesis.speak(msg); -} +}; // speak('Hello, World') -> plays the message ``` From eb92557dea511878f4365e124275bfe6f6aac27e Mon Sep 17 00:00:00 2001 From: Arjun Mahishi Date: Fri, 15 Dec 2017 00:23:10 +0530 Subject: [PATCH 188/202] Added snippet to convert number to array of digits --- snippets/number-to-array-of-digits.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 snippets/number-to-array-of-digits.md diff --git a/snippets/number-to-array-of-digits.md b/snippets/number-to-array-of-digits.md new file mode 100644 index 000000000..710540762 --- /dev/null +++ b/snippets/number-to-array-of-digits.md @@ -0,0 +1,17 @@ +### Number to array to digits + +use `parseInt()` to get only the integer part of the quotient. +use `Array.reverse()` to return the array in the same order as the number. + +```js +const num2array = (n) =>{ + let arr = []; + while (n>0) { + arr.push(n%10); + n = parseInt(n/10); + } + return arr.reverse(); +} + +// num2array(2334) -> [2, 3, 3, 4] +``` \ No newline at end of file From af3aa2d8dcaef0282e169b5a4179f8b1cc7e4767 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 20:53:53 +0200 Subject: [PATCH 189/202] Fix filename --- README.md | 17 +---------------- ...l).md => speech-synthesis-(experimental).md} | 0 2 files changed, 1 insertion(+), 16 deletions(-) rename snippets/{speech_synthesis-(experimental).md => speech-synthesis-(experimental).md} (100%) diff --git a/README.md b/README.md index 142e14a79..f15c1af45 100644 --- a/README.md +++ b/README.md @@ -818,22 +818,7 @@ const standardDeviation = (arr, usePopulation = false) => { [⬆ back to top](#table-of-contents) ## Media -### Speech synthesis (experimental) - -Use `SpeechSynthesisUtterance.voice` and `indow.speechSynthesis.getVoices()` to convert a message to speech. -Use `window.speechSynthesis.speak()` to play the message. - -Learn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance). - -```js -const speak = message => { - const msg = new SpeechSynthesisUtterance(message); - msg.voice = window.speechSynthesis.getVoices()[0]; - window.speechSynthesis.speak(msg); -}; -// speak('Hello, World') -> plays the message -``` - +undefined [⬆ back to top](#table-of-contents) ## Object diff --git a/snippets/speech_synthesis-(experimental).md b/snippets/speech-synthesis-(experimental).md similarity index 100% rename from snippets/speech_synthesis-(experimental).md rename to snippets/speech-synthesis-(experimental).md From 07166e9ff5b43672f4d87cdae55a86851f8cecc8 Mon Sep 17 00:00:00 2001 From: Arjun Mahishi Date: Fri, 15 Dec 2017 00:25:46 +0530 Subject: [PATCH 190/202] Fixed typo --- snippets/number-to-array-of-digits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/number-to-array-of-digits.md b/snippets/number-to-array-of-digits.md index 710540762..aa4652fa7 100644 --- a/snippets/number-to-array-of-digits.md +++ b/snippets/number-to-array-of-digits.md @@ -1,4 +1,4 @@ -### Number to array to digits +### Number to array of digits use `parseInt()` to get only the integer part of the quotient. use `Array.reverse()` to return the array in the same order as the number. From 9ef13d714009ab88b725c11446fe4567a0266f35 Mon Sep 17 00:00:00 2001 From: Arjun Mahishi Date: Fri, 15 Dec 2017 00:37:32 +0530 Subject: [PATCH 191/202] updated changes --- snippets/number-to-array-of-digits.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/snippets/number-to-array-of-digits.md b/snippets/number-to-array-of-digits.md index aa4652fa7..63fe6c907 100644 --- a/snippets/number-to-array-of-digits.md +++ b/snippets/number-to-array-of-digits.md @@ -5,12 +5,9 @@ use `Array.reverse()` to return the array in the same order as the number. ```js const num2array = (n) =>{ - let arr = []; - while (n>0) { - arr.push(n%10); - n = parseInt(n/10); - } - return arr.reverse(); + return (''+n).split('').map((i) =>{ + return parseInt(i); + }) } // num2array(2334) -> [2, 3, 3, 4] From 6fe3ea4cc658c73d7f9dbc8a1d961bda03506b24 Mon Sep 17 00:00:00 2001 From: Arjun Mahishi Date: Fri, 15 Dec 2017 00:44:39 +0530 Subject: [PATCH 192/202] updated changes --- snippets/number-to-array-of-digits.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/snippets/number-to-array-of-digits.md b/snippets/number-to-array-of-digits.md index 63fe6c907..9493c279f 100644 --- a/snippets/number-to-array-of-digits.md +++ b/snippets/number-to-array-of-digits.md @@ -1,7 +1,7 @@ ### Number to array of digits -use `parseInt()` to get only the integer part of the quotient. -use `Array.reverse()` to return the array in the same order as the number. +Convert the number to a string, split the string using `split()`. +use `parseInt()` to convert every element back to integer. ```js const num2array = (n) =>{ From 2c46861931b323fba2e27c52b93411bf514e4760 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 22:53:42 +0200 Subject: [PATCH 193/202] Update number-to-array-of-digits.md --- snippets/number-to-array-of-digits.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/snippets/number-to-array-of-digits.md b/snippets/number-to-array-of-digits.md index 9493c279f..f00a62b75 100644 --- a/snippets/number-to-array-of-digits.md +++ b/snippets/number-to-array-of-digits.md @@ -1,14 +1,9 @@ ### Number to array of digits -Convert the number to a string, split the string using `split()`. -use `parseInt()` to convert every element back to integer. +Convert the number to a string, use `split()` to convert build an array. +Use `Array.map()` and `parseInt()` to transform each value to an integer. ```js -const num2array = (n) =>{ - return (''+n).split('').map((i) =>{ - return parseInt(i); - }) -} - -// num2array(2334) -> [2, 3, 3, 4] -``` \ No newline at end of file +const digitize = n => (''+n).split('').map(i => parseInt(i)); +// digitize(2334) -> [2, 3, 3, 4] +``` From 0bbe323f70d47801326b5a7908578008febf8df5 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 23:00:38 +0200 Subject: [PATCH 194/202] Tag, lint, build --- README.md | 32 ++++++++++++++++++++++++++++++-- tag_database | 3 ++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f15c1af45..90e814bc8 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ * [Standard deviation](#standard-deviation) ### Media -* [Speech_synthesis (experimental)](#speech_synthesis-experimental) +* [Speech synthesis (experimental)](#speech-synthesis-experimental) ### Object * [Object from key value pairs](#object-from-key-value-pairs) @@ -99,6 +99,7 @@ * [Is string](#is-string) * [Is symbol](#is-symbol) * [Measure time taken by function](#measure-time-taken-by-function) +* [Number to array of digits](#number-to-array-of-digits) * [Ordinal suffix of number](#ordinal-suffix-of-number) * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) @@ -818,7 +819,22 @@ const standardDeviation = (arr, usePopulation = false) => { [⬆ back to top](#table-of-contents) ## Media -undefined +### Speech synthesis (experimental) + +Use `SpeechSynthesisUtterance.voice` and `indow.speechSynthesis.getVoices()` to convert a message to speech. +Use `window.speechSynthesis.speak()` to play the message. + +Learn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance). + +```js +const speak = message => { + const msg = new SpeechSynthesisUtterance(message); + msg.voice = window.speechSynthesis.getVoices()[0]; + window.speechSynthesis.speak(msg); +}; +// speak('Hello, World') -> plays the message +``` + [⬆ back to top](#table-of-contents) ## Object @@ -1051,6 +1067,18 @@ const timeTaken = callback => { [⬆ back to top](#table-of-contents) +### Number to array of digits + +Convert the number to a string, use `split()` to convert build an array. +Use `Array.map()` and `parseInt()` to transform each value to an integer. + +```js +const digitize = n => (''+n).split('').map(i => parseInt(i)); +// digitize(2334) -> [2, 3, 3, 4] +``` + +[⬆ back to top](#table-of-contents) + ### Ordinal suffix of number Use the modulo operator (`%`) to find values of single and tens digits. diff --git a/tag_database b/tag_database index 01c21bce9..7f81cbec1 100644 --- a/tag_database +++ b/tag_database @@ -49,6 +49,7 @@ is-symbol:utility last-of-list:array measure-time-taken-by-function:utility median-of-array-of-numbers:array +number-to-array-of-digits:utility object-from-key-value-pairs:object object-to-key-value-pairs:object ordinal-suffix-of-number:utility @@ -68,7 +69,7 @@ shuffle-array:array similarity-between-arrays:array sleep:function sort-characters-in-string-(alphabetical):string -speech_synthesis-(experimental):media +speech-synthesis-(experimental):media standard-deviation:math sum-of-array-of-numbers:array swap-values-of-two-variables:utility From 40843b252c636d54ebeb199e9a83a4030dc66009 Mon Sep 17 00:00:00 2001 From: Eric Wyne Date: Thu, 14 Dec 2017 13:09:08 -0800 Subject: [PATCH 195/202] round number to n digits --- snippets/round-number-to-n-digits.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/round-number-to-n-digits.md diff --git a/snippets/round-number-to-n-digits.md b/snippets/round-number-to-n-digits.md new file mode 100644 index 000000000..0c33b5b4f --- /dev/null +++ b/snippets/round-number-to-n-digits.md @@ -0,0 +1,9 @@ +### Round number to n digits + +Correctly rounds a number to the specified number of digits. + +```js +const round = (n, decimals = 0) => + Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`) +// round(1.005, 2) -> 1.01 +``` From 7ccc71134083898edfe6ae4a34a219c99a0d95ef Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 23:11:52 +0200 Subject: [PATCH 196/202] Create nth-element-of-array.md --- snippets/nth-element-of-array.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 snippets/nth-element-of-array.md diff --git a/snippets/nth-element-of-array.md b/snippets/nth-element-of-array.md new file mode 100644 index 000000000..15552d071 --- /dev/null +++ b/snippets/nth-element-of-array.md @@ -0,0 +1,11 @@ +### Nth element of array + +Use `Array.slice()` to get an array containing the nth element at the first place. +If the index is out of bounds, return `[]`. +Omit the second argument, `n`, to get the first element of the array. + +```js +const nth = (arr, n=0) => (n>0? arr.slice(n,n+1) : arr.slice(n))[0]; +// nth(['a','b','c'],1) -> 'b' +// nth(['a','b','b']-2) -> 'a' +``` From a2ab684cfc1de4fdc87e27e8ba0a2a8c193db530 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 23:15:34 +0200 Subject: [PATCH 197/202] Update round-number-to-n-digits.md --- snippets/round-number-to-n-digits.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/snippets/round-number-to-n-digits.md b/snippets/round-number-to-n-digits.md index 0c33b5b4f..a35308ce0 100644 --- a/snippets/round-number-to-n-digits.md +++ b/snippets/round-number-to-n-digits.md @@ -1,9 +1,9 @@ ### Round number to n digits -Correctly rounds a number to the specified number of digits. +Use `Math.round()` and template literals to round the number to the specified number of digits. +Omit the second argument, `decimals` to round to an integer. ```js -const round = (n, decimals = 0) => - Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`) +const round = (n, decimals=0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`); // round(1.005, 2) -> 1.01 ``` From 28bc2bef7c2db6cc9758860dfeddb21b5339b8f9 Mon Sep 17 00:00:00 2001 From: atomiks Date: Fri, 15 Dec 2017 08:17:21 +1100 Subject: [PATCH 198/202] Create shallow-clone-object.md We need a deep clone too but that's a different animal. `JSON.parse(JSON.stringify(obj))` is not very good because it strips functions, etc. --- snippets/shallow-clone-object.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 snippets/shallow-clone-object.md diff --git a/snippets/shallow-clone-object.md b/snippets/shallow-clone-object.md new file mode 100644 index 000000000..7993e8243 --- /dev/null +++ b/snippets/shallow-clone-object.md @@ -0,0 +1,12 @@ +### Shallow clone object + +Use the object spread operator to spread the properties of the target object into the clone. + +```js +const shallowClone = obj => ({ ...obj }); +/* +const a = { x: true, y: 1 }; +const b = shallowClone(a); +a === b -> false +*/ +``` From 82f5a478cca0d9bcb2a206136246058cc53de807 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 23:27:27 +0200 Subject: [PATCH 199/202] Update shallow-clone-object.md --- snippets/shallow-clone-object.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/shallow-clone-object.md b/snippets/shallow-clone-object.md index 7993e8243..c6873c0d8 100644 --- a/snippets/shallow-clone-object.md +++ b/snippets/shallow-clone-object.md @@ -1,6 +1,6 @@ ### Shallow clone object -Use the object spread operator to spread the properties of the target object into the clone. +Use the object `...spread` operator to spread the properties of the target object into the clone. ```js const shallowClone = obj => ({ ...obj }); From ec240463b51f0059b7b4e2c83cdefc8b4784d267 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 23:29:12 +0200 Subject: [PATCH 200/202] Tag, lint, build --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ tag_database | 3 +++ 2 files changed, 47 insertions(+) diff --git a/README.md b/README.md index 90e814bc8..367898d9e 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ * [Initialize array with values](#initialize-array-with-values) * [Last of list](#last-of-list) * [Median of array of numbers](#median-of-array-of-numbers) +* [Nth element of array](#nth-element-of-array) * [Pick](#pick) * [Shuffle array](#shuffle-array) * [Similarity between arrays](#similarity-between-arrays) @@ -71,6 +72,7 @@ * [Hamming distance](#hamming-distance) * [Percentile](#percentile) * [Powerset](#powerset) +* [Round number to n digits](#round-number-to-n-digits) * [Standard deviation](#standard-deviation) ### Media @@ -79,6 +81,7 @@ ### Object * [Object from key value pairs](#object-from-key-value-pairs) * [Object to key value pairs](#object-to-key-value-pairs) +* [Shallow clone object](#shallow-clone-object) ### String * [Anagrams of string (with duplicates)](#anagrams-of-string-with-duplicates) @@ -394,6 +397,20 @@ const median = arr => { [⬆ back to top](#table-of-contents) +### Nth element of array + +Use `Array.slice()` to get an array containing the nth element at the first place. +If the index is out of bounds, return `[]`. +Omit the second argument, `n`, to get the first element of the array. + +```js +const nth = (arr, n=0) => (n>0? arr.slice(n,n+1) : arr.slice(n))[0]; +// nth(['a','b','c'],1) -> 'b' +// nth(['a','b','b']-2) -> 'a' +``` + +[⬆ back to top](#table-of-contents) + ### Pick Use `Array.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. @@ -798,6 +815,18 @@ const powerset = arr => [⬆ back to top](#table-of-contents) +### Round number to n digits + +Use `Math.round()` and template literals to round the number to the specified number of digits. +Omit the second argument, `decimals` to round to an integer. + +```js +const round = (n, decimals=0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`); +// round(1.005, 2) -> 1.01 +``` + +[⬆ back to top](#table-of-contents) + ### Standard deviation Use `Array.reduce()` to calculate the mean, variance and the sum of the variance of the values, the variance of the values, then @@ -858,6 +887,21 @@ const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); // objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) ``` +[⬆ back to top](#table-of-contents) + +### Shallow clone object + +Use the object `...spread` operator to spread the properties of the target object into the clone. + +```js +const shallowClone = obj => ({ ...obj }); +/* +const a = { x: true, y: 1 }; +const b = shallowClone(a); +a === b -> false +*/ +``` + [⬆ back to top](#table-of-contents) ## String diff --git a/tag_database b/tag_database index 7f81cbec1..b2535a484 100644 --- a/tag_database +++ b/tag_database @@ -49,6 +49,7 @@ is-symbol:utility last-of-list:array measure-time-taken-by-function:utility median-of-array-of-numbers:array +nth-element-of-array:array number-to-array-of-digits:utility object-from-key-value-pairs:object object-to-key-value-pairs:object @@ -63,8 +64,10 @@ random-number-in-range:utility redirect-to-URL:browser reverse-a-string:string RGB-to-hexadecimal:utility +round-number-to-n-digits:math run-promises-in-series:function scroll-to-top:browser +shallow-clone-object:object shuffle-array:array similarity-between-arrays:array sleep:function From 224b698d4eb6559313ce2361bd75053c2eeab8df Mon Sep 17 00:00:00 2001 From: atomiks Date: Fri, 15 Dec 2017 08:43:47 +1100 Subject: [PATCH 201/202] Update measure-time-taken-by-function.md --- snippets/measure-time-taken-by-function.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/snippets/measure-time-taken-by-function.md b/snippets/measure-time-taken-by-function.md index 44e099d7e..ca476ac71 100644 --- a/snippets/measure-time-taken-by-function.md +++ b/snippets/measure-time-taken-by-function.md @@ -1,13 +1,14 @@ ### Measure time taken by function -Use `performance.now()` to get start and end time for the function, `console.log()` the time taken. -Pass a callback function as the argument. +Use `console.time()` and `console.timeEnd()` to measure the difference between the start and end times to determine how long the callback took to execute. ```js const timeTaken = callback => { - const t0 = performance.now(), r = callback(); - console.log(performance.now() - t0); + console.time('timeTaken'); + const r = callback(); + console.timeEnd('timeTaken'); return r; }; -// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) +// timeTaken(() => Math.pow(2, 10)) -> 1024 +// (logged): timeTaken: 0.02099609375ms ``` From c286d551827e716b6f8fc858f1f223f5659472c3 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 23:47:46 +0200 Subject: [PATCH 202/202] Build README --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 367898d9e..7160b9afb 100644 --- a/README.md +++ b/README.md @@ -1097,16 +1097,17 @@ const isSymbol = val => typeof val === 'symbol'; ### Measure time taken by function -Use `performance.now()` to get start and end time for the function, `console.log()` the time taken. -Pass a callback function as the argument. +Use `console.time()` and `console.timeEnd()` to measure the difference between the start and end times to determine how long the callback took to execute. ```js const timeTaken = callback => { - const t0 = performance.now(), r = callback(); - console.log(performance.now() - t0); + console.time('timeTaken'); + const r = callback(); + console.timeEnd('timeTaken'); return r; }; -// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) +// timeTaken(() => Math.pow(2, 10)) -> 1024 +// (logged): timeTaken: 0.02099609375ms ``` [⬆ back to top](#table-of-contents)