From 8e6f5b25703330afc870821b19808b9eb17db48e 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 a1a5fb291b158a00602c834a4328f3d806237314 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 aeb5d14f46bb6ae14fe9e301ca4dee689170a788 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 d4681ce4c30a42944ba9152969b58ad9c0ce4dc3 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 65126fe4ccf6dcb7b74f122797b7ddd067dbfa94 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 c9116d54b8bca716d7ca8bb42cc9e87bb75fab0a 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 8ff6d9bff11d461f7cd0b827cdb8f79b1322f5b5 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 8250b4e891edcc149b9047367ce1c464e63e3ad2 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 393b1a6a59d30d09fd54988a1fe20fc0fe4e3416 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 e602ba01953d840359778e35b73f27d8b6c22342 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 101bcf6d8b96863d2366113517f5bffabb67140e 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 ea98b55d31e09edd1ddbddc54cd4740018fddaac 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 76a1ec7b616833e48d96f65ca2c2cfc22ef4f67c 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 b1982f556e47f8a3a49e78bd3b8597975c5027fb 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 8463f2bfb8ea0f3d070a6e80a9a80c293ab10ba7 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 ba60546a65f7be3d9ea8284127d9c90931c5b6d5 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 9fc483b30fd88dc1ab5dfb1efec5fa12f8b7539c 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 5b22c9a3db273b30728f83dd2bda36605d508abb 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 bc131937970ab9e23689c386e7b694decc0f5301 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 da0b103de0b372c255f180a1f81e1b151da901fa 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 fa1c842d1301499e1674533887d15ea22466125f 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 94a582518cbf051aee4d657cd10998ee7fc45b11 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 00cc6c396e4a012eff880e1f1308f93f4207794a 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 25c112c24e94701101f8b7bb5d826d33c0421908 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 a29c46fa1c7f1f05574cc3abf4b6bdbc83f493cd 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 4a3552793518ec0d6759401c0a38328e1ecb5478 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 19cefca9bbfcae5604917182fac9067dc6e7576d 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 71208b5e910169446c6a7a52b3371276cd5ef1c0 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 84e5544b785d5c81d7a21a72b43232f548d5b2b8 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 338973728e30f1d298dcc855906c4bbde5dc5d6b 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 e9d912c2ac73b5de366706a9f2f65c835c99ad38 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 af07cded052ae427f1418c7a7977ee1683484ce3 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 7eaa437dd15d9289816fd1cf76e8f4628dcfee11 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 64d28164ef291e30f3c4a9692041392a88770dbd 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 3e763d0b2337905c38dfc8d68ed23098e5cd16e3 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 46e8ff5d24ba3425d0e1e9964e639a387eae713b 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 b28a1bd212b0401aec2fc148265472ab924cbf5b 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 4bbc98b0ca0b80e2feea17eddf93a11a0fa011da 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 f6c181e0f4e03d523070448dae937455f0a82134 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 cd768292627e659fa17231a5a818ceb6cd005ef1 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 e59fe392d131b1be73cd60f770d13e5e77c6c14f 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 19cff66dd43adc506151cb7a2a0e1d91a47eb182 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 32d182d1f66bf73b85ad7c0c2f7b142f51699cf3 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 b9edc9a85296bfdf644099bb3f4d3dafbd5fe3fc 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 d739f461308382b5c1ec68078e90280632a922ca 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 e91fc01d2507f885ea43d1497bf1decaae103269 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 8c03d44fbe39db1c38cf7cdb012d3f0f90101ab6 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 3676d11b0c8b2fd3f104a38ab1dae58a296cac0c 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 09bac3fb7fea109dd6ece7deb1a083ed661e174a 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 0fd49f261dd0ac9a4412b242c6ed0cc7c20f2992 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 31f7c652e283518881a429448e09ef5f26dfe9ed 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 b6157f8b953f9818caba043679840d79332dedba 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 75673219dc9847f37dd5e78d5a9071386632beaa 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 de32a204d2659110ee9c91fc054d75f65a38aca9 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 ddd72538f1306460c8fa5dfc7b176ab00e7d2ab6 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 e5635a402cbb3171a7fa97e4e0f96f8f182c487f 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 e652559fdb26ae27d7a9f28c12e2502778527e8d 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 eb817e71d253486bd37a68a3e9a517ce0009225b 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 9ca866418d75b4611d500628773fc93978184c17 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 1e8d519875ea066f49c1bae3f52115de187504b5 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 7490c51ae783097d5e497d20a1528680f1d8b10a 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 32b9834837f1018ec5b3324af3c921277534c5d6 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 add7435757b95f4c4eb883814cb40cdf79d6614d 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 306e0f0ecf2b87f096f80bfdd0221307bd6d862f 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 97d727f068264bf2d9a39be3ef397da4a09c700e 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 caa0137cfc7199f6f94be061551b69f4c7c8f410 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 7df83ac6b3bafcd3f983413f6bbc158d68ac432a 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 91e6a29c1345756aec84b28f0de3e067fcdecfd5 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 9846e4f69bc367853bda33c6b91f3b435b919dd5 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 231ae4e57d0787c38f42c2fe4207ae253eaa961c 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 0898dcb44c659e82a67f2a0f33108042c716ca3f 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 b70c76afd3309d51d6fbd67bf2836f31f062a956 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 9fbedeb98102e972a6ab39c489188201ba2698ba 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 a42d7ebe488e94975ec75b80baae6ce92f023d4e 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 bb4f1c6704678aa5519b3debda86a711e4d6d5ad 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 b4668466a519f7e4f08a1b8067f1c7156a07a424 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 fea9f8553206caf7a3b530271a0483caa653ad19 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 210104ef7a0e97634488b52f5bcdc0ec519e7479 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 65a70a1ed609ac42600a54c2fd841720dda62e87 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 7e4ab9cbf4f281ac826c834c83826f00eeb97823 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 8e2d635d49eeab8a2739e8294839fbd453445442 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 35c7669773588cac1d802a07ebfae1a0be4e3e36 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 f6426792d33f6853ae7b00e598e64a02519939ca 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 5a0d076a81d7ecfe3fb1995110a073a0662fcc60 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 91afd76dcec312b65933fe48f9d5a79fd4c472a4 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 1bd89ffe7537f40de4049b213f10b2d43644b835 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 c236de3e67d68e4d9faf283dec86a0e1f333046d 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 143c024968413360c73b00fc59bf471c6751ab75 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 c4534cfbf3d7c12802889c56dcdff79c8a5c2c05 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 2d149930c6a188044ad5944ed869b694a5376ec7 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 9efd81c1984d580c292a24f18c8616c9d696ec2d 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 fc13b5d9303934638bb2383ffaf015d2ce564b9a 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 e8a03e358c835b1b1afdf26cf3faf619a838ea0b 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 50ea77d0751e591d9d34df515b260ed3cf9f7100 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 824f8449dcdeaac091b26bff3aa4356b4b76d706 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 6f53f7580a27d2b8e77e6b2bcd6049e3d3933893 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 5bd16b109d71774aa6dd392a6eddb1a389d3a13f 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 3e307273dec6bcea0881e97d0e9d9c2a01bd8d5e 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 682f172645a7b16f640f966f25b02de0cd12f55b 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 33fc7245790f12068dbe4ce0210a86cc0df78dfd 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 2a3654ccac1331c0feba27b29db10604c02295cd 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 d66511410af1bbb9c479791606ed631ca4dd203a 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 ba168858126dda002647c7fcfe45db8451840a01 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 0cb38063c5fb774ea1f1f4435aa5d1206cba2300 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 d87c3974182a00c5bdabc1b6025ae179f15a9bb7 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 a07dc3ae6d3118c3a291e3fe432ec237e199b90f 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 84cfb15d491c2191ac81e254670a40473d711657 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 b6de81b2fba205f376fdbc3768452d11d2cc65fe 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 2ab04db023209d1739549183eac1b0c17e75d335 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 fa906f20c20f2cb6a678507210a37d8f676136a1 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 3ddd59636d0bd45c055d817d24248542f2490381 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 117a67fb2448814132331373ff9867f4a4a1a981 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 4b680599099a71b5d43e7eca804bd13ef3ddbc0e 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 c0484daeb4c10d4caa32146d9f4f3571dbf7207a 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 49396115417775b3246ac4879cecb65579529724 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 9a8f4c5549791831029325abf8d26d172a65b782 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 48027ded500890939952229a102149a7858d9cf9 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 f521cdf2c4f0e2d4c554dd24dc438698361ca754 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 9a9379aa614faa112dc53ecbccf34380adda4edc 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 b7f716ef4294ce96404fb1317faa428f64726c75 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 bf499d9f2c05ef44baeeb4e66b51e1dad805d5be 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 51f376796b1e6a93a33ab67c0b8ad6e669a3a43f 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 34fdbe917300bdd515cf1692877df0a0be1fbf37 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 a77f68d26ba95717be59700fa872d67b9b7048f8 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 2c83d0658dc674ca5fe0430f905a186c5a5d1ed9 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 011194319b9d918f3804dd0080fe4d36598f1092 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 c74ef2837dc485f3236ab51f6adadcc85ae9467f 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 4cf96c4d926430a3654d5b1ad8044e1191b4816b 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 cd43ed8b56258cf213ac03c62dea4cee2a17ba24 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 e0f79f18b1e6e2a31ff9c09760a5be360095cfbd 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 be8d285faf1b898a9e48fc410dda04f608684811 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 f162c9bd019919ff94c23215ff4b05eaf1bfab44 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 38e5a30585433ef4c67190df8c00d650a96d7ab3 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 6aa980541bed8c54306b4fc348282318eadf6120 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 c37d4a24182031736dd78b915b7b4f32fe6bbf37 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 7ca2851fcee47924b66a3dfc5a320e3ca7bdf3e8 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 fbe304288ffe6c8d03d6f3f84e7f3d9526303509 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 d2302c083cb7e1b97e154926b2d3db3b1ba7c107 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 e7d1600515f0718db29e13e59369666d99189384 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 f5bda230e4c938418a15a740f8a18f176159a362 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 19246fc689d8724d8d2507b76deee80480999dcc 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 3d15d16dd666d2f05888d6204ac2c3d1b0c01ca1 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 78d5fa31f8fa95ab80aa9916cb41ce282dfdb7b9 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 c30cf9307df0f125359872677068aa0a56072108 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 d304cb6e7d1b2b559968d261cbbc80a0e5c882bd 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 df5428c64846b4e7dd52f8d1d0a37b6da89fcda2 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 3b0a8885cc03b266144c7410ea745aec72339a82 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 2346be526797534ec871f7787be653c899f8a540 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 4583d71edc70295d3ebcb1b9d929ae21c05e360f 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 9bd37780557ff219fd6a1e865f9779550106335e 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 5cd1ddd83ea564cdd26bc4db85dd26790235bb43 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 7de373b34f03a9402c72b4ebef2ce0e581905256 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 1e0f46cb6c7753093e03d365dfce08a96d89db8c 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 ac5c3d3f15d976db43bafe612074d47ebae08ae8 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 54dc5e9e39b6b7384f3e265ecfa9ac4517010ae4 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 c54c4db01836a2606ba839464c8d525f4d531042 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 114fd89732662af46807de041fbed8bd76d989af 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 44feb706cd537c5979cd5b837e0b904d4a78961f 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 76fc2317d3a79010153f9939b828f1c17d25a415 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 c42ed5f746a573536ec2bc798e4416e34d582bb5 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 22331697df69b65ac7ed619dd6608a454574ae3d 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 4ae535d46deadf5b410452db6d734f6c00dc4f20 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 21b8b18f6bec3f7fca5aa29c668a86be1d160799 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 8244c204dde346fe9e6bd7864fd4ef947c274eb8 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 e9e63a96304251247b0b437e5fde762819008540 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 b106585c08d53e324b902a319ecba5e450d486de 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 4a71bb886ff5b39e3fb809a7a86abc3cbda410fd 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 e5c1d29ce6d074e90f7dd5094e0c3d649bb44a04 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 a1341458ab31a8aa457d833e48f9ccfd8ca8c519 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 e4e8ea98dc509aee3e0938eb952e7a476d229382 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 06018e143aa086bba8081025aa4fdbcfa06955ee 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 0ab7ee90e29022a3eb9ecb51398a3a0f8b81f4a6 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 cd4d6ba9e850ebd38cf038cfea940be7154ee133 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 2350460ed666c7ead54780ecf7f23c0b9925e664 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 530e4e411abb8340b828cdf59bd327a34b14acda 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 8af4dfaa738029c001fb15522b0d6570e155673e 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 0a2175e00ef3b4ed145c0af36b582c550c1c7542 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 20e8633917beb99531e3a3628c6a63dd16ffb4ad 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 e0693339b40a4252b2ca972621202c6ed4f5dab0 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 3549379bcb3a68a466092a8c390acdb3abe7e7a9 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 f81b49f9f5ad7fedce18d57538b7b51a5be01018 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 26c8055fa45f899478f773fef375d437a980b96e 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 db4e2478cd503fe72885e618144711505448947f 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 240eda38099986f93858e16c08fdaf14d780385f 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 744c6f359dbbf4ad05f18f692e82049b4c92d3a2 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 3f8ca8d615cf994a199d8f717147550acb5ab62b 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 3fde98fc2e92f325c33c9b8217927a42bce5fff5 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 d15ef2afa989d7f4477bb27e1e0494aae06e5505 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 a14f144436aef18eb28664630a9c5a30bbd0b877 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 655584d0ed8d6dc91c0a805c40a8a581da41bdc3 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 6ef96cc3a616f599517bc32801a177bc66538608 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 f827f0d1090bf77f8940f59727a4cca0027d3456 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 69b3e2b97fa775cfae4e35462303e3e7b7856c59 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 aafeaaabdac18d330ea3e62f1318cca0571fac92 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 d9821bfafdfe3cbcde5fb32fda9eb94736f762d1 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 9d29636e43b84721ca02b34f9bfe6719e770b546 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 cbe7d80ba573333103ea0cc1e26053f32a198842 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 6ced078936f9c30fdcac057610c9db16058bc800 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 db097c03f266393ee384b4633c1077d7e84defb9 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 6074aa67545312b18d84336b8a31f408d3dcd029 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 94799c46d91efd79c319e8b59a80c3b63a4b7549 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 ddbcf684560e19b4449b37ffeb06f3a46a2067b6 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)