From 15827ebf23357a13781091afc9d0fb2de87dda09 Mon Sep 17 00:00:00 2001 From: Adrian Klimek Date: Tue, 12 Dec 2017 22:37:34 +0100 Subject: [PATCH 01/46] 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 05d3a8b0e2cc055b0a33aaa6472cee53bf2c136d Mon Sep 17 00:00:00 2001 From: Adrian Klimek Date: Tue, 12 Dec 2017 23:11:03 +0100 Subject: [PATCH 02/46] 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 54f163b9f105a82a6b225a274cc7a96ceb7b4553 Mon Sep 17 00:00:00 2001 From: Michael Goldspinner Date: Wed, 13 Dec 2017 09:01:14 -0500 Subject: [PATCH 03/46] 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 3a9c322d138676367d8ca05d237d5630a3fa64cb Mon Sep 17 00:00:00 2001 From: Adrian Klimek Date: Wed, 13 Dec 2017 20:02:29 +0100 Subject: [PATCH 04/46] 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 4a661d70f2eec0a2dec891d8fed38bdc5cfeaf55 Mon Sep 17 00:00:00 2001 From: iamsoorena Date: Thu, 14 Dec 2017 00:10:56 +0330 Subject: [PATCH 05/46] add sleep function - making delays in async functions --- snippets/sleep.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 snippets/sleep.md diff --git a/snippets/sleep.md b/snippets/sleep.md new file mode 100644 index 000000000..4a7e8916b --- /dev/null +++ b/snippets/sleep.md @@ -0,0 +1,12 @@ +### Sleep + +If you have an async function and you want to delay executing part of it. you can put your async function to sleep(in miliseconds). + +```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.'); +// } +``` From e8d9acae9a3d9dd07a4e06716ceb63a2dc137a37 Mon Sep 17 00:00:00 2001 From: Elder Henrique Souza Date: Wed, 13 Dec 2017 18:49:12 -0200 Subject: [PATCH 06/46] group by Tried to reproduce the groupBy behaviour from the lodash lib. https://lodash.com/docs/4.17.4#groupBy --- snippets/group-by | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 snippets/group-by diff --git a/snippets/group-by b/snippets/group-by new file mode 100644 index 000000000..53383db3a --- /dev/null +++ b/snippets/group-by @@ -0,0 +1,16 @@ +### Group by + +Passing an array of values, a function or a property name thats going to be run against each value in the array, +returns an object where the keys are the mapped results and the values is an array of the original values that generated the same results. + +```js +const groupBy = (values, fn) => { + return (typeof fn === 'function' ? values.map(fn) : values.map((val) => val[fn])) + .reduce((acc, val, i) => { + acc[val] = acc[val] === undefined ? [values[i]] : acc[val].concat(values[i]); + return acc; + }, {}); +} +// groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]} +// groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} +``` From b2d737bec5cb1f0e9242d0fdcb87d3ed7c0a2d67 Mon Sep 17 00:00:00 2001 From: King Date: Wed, 13 Dec 2017 16:51:34 -0500 Subject: [PATCH 07/46] 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 bf855e55e228991e864adc245504099df8342699 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 00:05:44 +0200 Subject: [PATCH 08/46] Added linting, processed current snippets --- README.md | 75 +- currentSnippet.js | 3 + package-lock.json | 1421 +++++++++++++++++ package.json | 4 +- scripts/builder.js | 4 + scripts/lintSnippet.js | 31 + semi-snippets.js | 242 +++ snippets.js | 302 ++++ snippets/URL-parameters.md | 2 +- snippets/UUID-generator.md | 2 +- .../anagrams-of-string-(with-duplicates).md | 8 +- snippets/average-of-array-of-numbers.md | 3 +- snippets/bottom-visible.md | 2 +- snippets/capitalize-first-letter.md | 2 +- snippets/chain-asynchronous-functions.md | 2 +- snippets/chunk-array.md | 2 +- snippets/deep-flatten-array.md | 2 +- snippets/fibonacci-array-generator.md | 4 +- snippets/flatten-array.md | 2 +- snippets/get-native-type-of-value.md | 2 +- snippets/get-scroll-position.md | 4 +- snippets/greatest-common-divisor-(GCD).md | 2 +- snippets/hamming-distance.md | 2 +- snippets/initial-of-list.md | 2 +- snippets/initialize-array-with-range.md | 2 +- snippets/measure-time-taken-by-function.md | 2 +- snippets/median-of-array-of-numbers.md | 4 +- snippets/object-from-key-value-pairs.md | 2 +- snippets/powerset.md | 2 +- snippets/randomize-order-of-array.md | 2 +- snippets/scroll-to-top.md | 6 +- snippets/shuffle-array-values.md | 4 +- ...ort-characters-in-string-(alphabetical).md | 2 +- snippets/sum-of-array-of-numbers.md | 2 +- snippets/truncate-a-string.md | 2 +- 35 files changed, 2079 insertions(+), 76 deletions(-) create mode 100644 currentSnippet.js create mode 100644 scripts/lintSnippet.js create mode 100644 semi-snippets.js create mode 100644 snippets.js diff --git a/README.md b/README.md index b77013e78..52a314f15 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -78,10 +78,10 @@ Base cases are for string `length` equal to `2` or `1`. ```js const anagrams = str => { - if(str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; - return str.split('').reduce( (acc, letter, i) => - acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => letter + val )), []); -} + if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; + return str.split('').reduce((acc, letter, i) => + acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)), []); +}; // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` @@ -90,8 +90,7 @@ const anagrams = str => { Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. ```js -const average = arr => - arr.reduce( (acc , val) => acc + val, 0) / arr.length; +const average = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length; // average([1,2,3]) -> 2 ``` @@ -100,7 +99,7 @@ const average = arr => Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible. ```js -const bottomVisible = _ => +const bottomVisible = _ => document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; // bottomVisible() -> true ``` @@ -121,7 +120,7 @@ Omit the `lowerRest` parameter to keep the rest of the string intact, or set it ```js const capitalize = (str, lowerRest = false) => - str.slice(0, 1).toUpperCase() + (lowerRest? str.slice(1).toLowerCase() : str.slice(1)); + str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); // capitalize('myName', true) -> 'Myname' ``` @@ -130,7 +129,7 @@ const capitalize = (str, lowerRest = false) => Loop through an array of functions containing asynchronous events, calling `next` when each asynchronous event has completed. ```js -const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); } +const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); }; /* chainAsync([ next => { console.log('0 seconds'); setTimeout(next, 1000); }, @@ -159,7 +158,7 @@ If the original array can't be split evenly, the final chunk will contain the re ```js const chunk = (arr, size) => - Array.apply(null, {length: Math.ceil(arr.length/size)}).map((v, i) => arr.slice(i*size, i*size+size)); + Array.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` @@ -207,7 +206,7 @@ Use `Array.reduce()` to get all elements that are not arrays, flatten each eleme ```js const deepFlatten = arr => - arr.reduce( (a, v) => a.concat( Array.isArray(v) ? deepFlatten(v) : v ), []); + arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []); // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] ``` @@ -274,8 +273,8 @@ Create an empty array of the specific length, initializing the first two values Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. ```js -const fibonacci = n => - Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),[]); +const fibonacci = n => + Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []); // fibonacci(5) -> [0,1,1,2,3] ``` @@ -293,7 +292,7 @@ const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexO Use `Array.reduce()` to get all elements inside the array and `concat()` to flatten them. ```js -const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); +const flatten = arr => arr.reduce((a, v) => a.concat(v), []); // flatten([1,[2],3,4]) -> [1,2,3,4] ``` @@ -321,7 +320,7 @@ Returns lower-cased constructor name of value, "undefined" or "null" if value is ```js const getType = v => - v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); + v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); // getType(new Set([1,2,3])) -> "set" ``` @@ -332,8 +331,8 @@ You can omit `el` to use a default value of `window`. ```js const getScrollPos = (el = window) => - ( {x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, - y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop} ); + ({x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, + y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop}); // getScrollPos() -> {x: 0, y: 200} ``` @@ -344,7 +343,7 @@ Base case is when `y` equals `0`. In this case, return `x`. Otherwise, return the GCD of `y` and the remainder of the division `x/y`. ```js -const gcd = (x , y) => !y ? x : gcd(y, x % y); +const gcd = (x, y) => !y ? x : gcd(y, x % y); // gcd (8, 36) -> 4 ``` @@ -355,7 +354,7 @@ Count and return the number of `1`s in the string, using `match(/1/g)`. ```js const hammingDistance = (num1, num2) => - ((num1^num2).toString(2).match(/1/g) || '').length; + ((num1 ^ num2).toString(2).match(/1/g) || '').length; // hammingDistance(2,3) -> 1 ``` @@ -373,7 +372,7 @@ const head = arr => arr[0]; Return `arr.slice(0,-1)`. ```js -const initial = arr => arr.slice(0,-1); +const initial = arr => arr.slice(0, -1); // initial([1,2,3]) -> [1,2] ``` @@ -384,7 +383,7 @@ You can omit `start` to use a default value of `0`. ```js const initializeArrayRange = (end, start = 0) => - Array.apply(null, Array(end-start)).map( (v,i) => i + start ); + Array.apply(null, Array(end - start)).map((v, i) => i + start); // initializeArrayRange(5) -> [0,1,2,3,4] ``` @@ -417,7 +416,7 @@ const timeTaken = callback => { const t0 = performance.now(), r = callback(); console.log(performance.now() - t0); return r; -} +}; // timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) ``` @@ -428,9 +427,9 @@ Return the number at the midpoint if `length` is odd, otherwise the average of t ```js const median = arr => { - const mid = Math.floor(arr.length / 2), nums = arr.sort((a,b) => a - b); + const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; -} +}; // median([5,6,50,1,-5]) -> 5 // median([0,10,-2,7]) -> 3.5 ``` @@ -440,7 +439,7 @@ const median = arr => { Use `Array.reduce()` to create and combine key-value pairs. ```js -const objectFromPairs = arr => arr.reduce((a,v) => (a[v[0]] = v[1], a), {}); +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); // objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} ``` @@ -470,7 +469,7 @@ Use `Array.reduce()` combined with `Array.map()` to iterate over elements and co ```js const powerset = arr => - arr.reduce( (a,v) => a.concat(a.map( r => [v].concat(r) )), [[]]); + arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); // powerset([1,2]) -> [[], [1], [2], [2,1]] ``` @@ -515,7 +514,7 @@ const randomInRange = (min, max) => Math.random() * (max - min) + min; Use `Array.sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. ```js -const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); +const randomizeOrder = arr => arr.sort((a, b) => Math.random() >= 0.5 ? -1 : 1); // randomizeOrder([1,2,3]) -> [1,3,2] ``` @@ -567,11 +566,11 @@ Scroll by a fraction of the distance from top. Use `window.requestAnimationFrame ```js const scrollToTop = _ => { const c = document.documentElement.scrollTop || document.body.scrollTop; - if(c > 0) { + if (c > 0) { window.requestAnimationFrame(scrollToTop); - window.scrollTo(0, c - c/8); + window.scrollTo(0, c - c / 8); } -} +}; // scrollToTop() ``` @@ -583,8 +582,8 @@ Use `Array.sort()` to sort the elements of the original array based on the rando ```js const shuffle = arr => { let r = arr.map(Math.random); - return arr.sort((a,b) => r[a] - r[b]); -} + return arr.sort((a, b) => r[a] - r[b]); +}; // shuffle([1,2,3]) -> [2, 1, 3] ``` @@ -603,7 +602,7 @@ Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, ```js const sortCharactersInString = str => - str.split('').sort( (a,b) => a.localeCompare(b) ).join(''); + str.split('').sort((a, b) => a.localeCompare(b)).join(''); // sortCharactersInString('cabbage') -> 'aabbceg' ``` @@ -612,7 +611,7 @@ const sortCharactersInString = str => Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. ```js -const sum = arr => arr.reduce( (acc , val) => acc + val, 0); +const sum = arr => arr.reduce((acc, val) => acc + val, 0); // sum([1,2,3,4]) -> 10 ``` @@ -642,7 +641,7 @@ Return the string truncated to the desired length, with `...` appended to the en ```js const truncate = (str, num) => - str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; + str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; // truncate('boomerang', 7) -> 'boom...' ``` @@ -663,7 +662,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => url.match(/([^?=&]+)(=([^&]*))?/g).reduce( - (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')+1), a), {} + (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} ``` @@ -674,7 +673,7 @@ Use `crypto` API to generate a UUID, compliant with [RFC4122](https://www.ietf.o ```js const uuid = _ => - ( [1e7]+-1e3+-4e3+-8e3+-1e11 ).replace( /[018]/g, c => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ); // uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' diff --git a/currentSnippet.js b/currentSnippet.js new file mode 100644 index 000000000..544a140b9 --- /dev/null +++ b/currentSnippet.js @@ -0,0 +1,3 @@ + +const valueOrDefault = (value, d) => value || d; +// valueOrDefault(NaN, 30) -> 30 diff --git a/package-lock.json b/package-lock.json index 50c9abf8a..be8bcab8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,40 @@ "negotiator": "0.6.1" } }, + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==" + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=" + }, "ansi-align": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", @@ -26,6 +60,11 @@ "string-width": "2.1.1" } }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" + }, "ansi-regex": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", @@ -79,16 +118,98 @@ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, "array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" }, + "array.prototype.find": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz", + "integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=", + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.10.0" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, "async-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -183,6 +304,24 @@ "repeat-element": "1.1.2" } }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" + }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", @@ -227,11 +366,34 @@ "readdirp": "2.1.0" } }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" + }, "cli-boxes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "requires": { + "restore-cursor": "1.0.1" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -265,6 +427,16 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, "concurrently": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.5.1.tgz", @@ -304,6 +476,11 @@ "utils-merge": "1.0.0" } }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -341,6 +518,14 @@ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "0.10.37" + } + }, "date-fns": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz", @@ -354,11 +539,64 @@ "ms": "0.7.1" } }, + "debug-log": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", + "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=" + }, "deep-extend": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "deglob": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.0.tgz", + "integrity": "sha1-TUSr4W7zLHebSXK9FBqAMlApoUo=", + "requires": { + "find-root": "1.1.0", + "glob": "7.1.2", + "ignore": "3.3.7", + "pkg-config": "1.1.1", + "run-parallel": "1.1.6", + "uniq": "1.0.1" + } + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, "depd": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", @@ -369,6 +607,14 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "doctrine": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", + "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "requires": { + "esutils": "2.0.2" + } + }, "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", @@ -402,11 +648,105 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es-abstract": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, + "es5-ext": { + "version": "0.10.37", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", + "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, "es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=" }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -417,11 +757,288 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "requires": { + "babel-code-frame": "6.26.0", + "chalk": "1.1.3", + "concat-stream": "1.6.0", + "debug": "2.2.0", + "doctrine": "2.0.2", + "escope": "3.6.0", + "espree": "3.5.2", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.7", + "imurmurhash": "0.1.4", + "inquirer": "0.12.0", + "is-my-json-valid": "2.16.1", + "is-resolvable": "1.0.1", + "js-yaml": "3.10.0", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "1.2.1", + "progress": "1.1.8", + "require-uncached": "1.0.3", + "shelljs": "0.7.8", + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1", + "table": "3.8.3", + "text-table": "0.2.0", + "user-home": "2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "eslint-config-semistandard": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-semistandard/-/eslint-config-semistandard-11.0.0.tgz", + "integrity": "sha1-RO73z9/Uchnjp7gbkbVA6IC7JhU=" + }, + "eslint-config-standard": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", + "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=" + }, + "eslint-config-standard-jsx": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.1.tgz", + "integrity": "sha1-zU5GPQJo4tnnB/YfQvc/WzMzxkI=" + }, + "eslint-import-resolver-node": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz", + "integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=", + "requires": { + "debug": "2.2.0", + "object-assign": "4.1.1", + "resolve": "1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", + "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", + "requires": { + "debug": "2.6.9", + "pkg-dir": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "eslint-plugin-import": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz", + "integrity": "sha1-crowb60wXWfEgWNIpGmaQimsi04=", + "requires": { + "builtin-modules": "1.1.1", + "contains-path": "0.1.0", + "debug": "2.2.0", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "0.2.3", + "eslint-module-utils": "2.1.1", + "has": "1.0.1", + "lodash.cond": "4.5.2", + "minimatch": "3.0.4", + "pkg-up": "1.0.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + } + } + }, + "eslint-plugin-node": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-4.2.3.tgz", + "integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==", + "requires": { + "ignore": "3.3.7", + "minimatch": "3.0.4", + "object-assign": "4.1.1", + "resolve": "1.5.0", + "semver": "5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + } + } + }, + "eslint-plugin-promise": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", + "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=" + }, + "eslint-plugin-react": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz", + "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=", + "requires": { + "array.prototype.find": "2.0.4", + "doctrine": "1.5.0", + "has": "1.0.1", + "jsx-ast-utils": "1.4.1", + "object.assign": "4.0.4" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + } + } + }, + "eslint-plugin-standard": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz", + "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=" + }, + "espree": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", + "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "requires": { + "acorn": "5.2.1", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37" + } + }, "event-stream": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", @@ -450,6 +1067,11 @@ "strip-eof": "1.0.0" } }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=" + }, "expand-brackets": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", @@ -474,6 +1096,11 @@ "is-extglob": "1.0.0" } }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, "faye-websocket": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", @@ -482,6 +1109,24 @@ "websocket-driver": "0.7.0" } }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -511,6 +1156,31 @@ "unpipe": "1.0.0" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -524,6 +1194,11 @@ "for-in": "1.0.2" } }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -544,11 +1219,52 @@ "universalify": "0.1.1" } }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=" + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "requires": { + "is-property": "1.0.2" + } + }, + "get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=" + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, "glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", @@ -574,6 +1290,31 @@ "ini": "1.3.5" } }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, "got": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", @@ -597,6 +1338,14 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "requires": { + "function-bind": "1.1.1" + } + }, "has-ansi": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", @@ -637,6 +1386,11 @@ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz", "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE=" }, + "ignore": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==" + }, "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", @@ -652,6 +1406,15 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -662,6 +1425,99 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "requires": { + "ansi-escapes": "1.4.0", + "ansi-regex": "2.1.1", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.2.0", + "figures": "1.7.0", + "lodash": "4.17.4", + "readline2": "1.0.1", + "run-async": "0.1.0", + "rx-lite": "3.1.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -675,6 +1531,16 @@ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -720,6 +1586,17 @@ "is-path-inside": "1.0.1" } }, + "is-my-json-valid": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", + "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, "is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", @@ -738,6 +1615,19 @@ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "requires": { + "is-path-inside": "1.0.1" + } + }, "is-path-inside": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", @@ -756,11 +1646,29 @@ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, "is-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "1.0.1" + } + }, + "is-resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", + "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==" + }, "is-retry-allowed": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", @@ -771,6 +1679,11 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" + }, "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", @@ -794,6 +1707,28 @@ "isarray": "1.0.0" } }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "0.0.0" + } + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -802,6 +1737,21 @@ "graceful-fs": "4.1.11" } }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=" + }, + "jsx-ast-utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz", + "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=" + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -818,6 +1768,15 @@ "package-json": "4.0.1" } }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, "linkify-it": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz", @@ -846,6 +1805,40 @@ "serve-index": "1.9.1" } }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + } + } + }, "lodash": { "version": "4.17.4", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", @@ -900,6 +1893,11 @@ "lodash.keys": "3.1.2" } }, + "lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=" + }, "lodash.defaults": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-3.1.2.tgz", @@ -1029,6 +2027,21 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, "morgan": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz", @@ -1061,6 +2074,16 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -1132,6 +2155,21 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=" + }, + "object.assign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz", + "integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw=", + "requires": { + "define-properties": "1.1.2", + "function-bind": "1.1.1", + "object-keys": "1.0.11" + } + }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", @@ -1154,6 +2192,19 @@ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" + }, "opn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz", @@ -1162,11 +2213,42 @@ "is-wsl": "1.1.0" } }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=" + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "1.1.0" + } + }, "package-json": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", @@ -1189,11 +2271,27 @@ "is-glob": "2.0.1" } }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "1.3.1" + } + }, "parseurl": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "2.0.1" + } + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1209,6 +2307,11 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" + }, "pause-stream": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", @@ -1222,6 +2325,74 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-conf": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.0.0.tgz", + "integrity": "sha1-BxyHZQQDvM+5xif1h1G/5HwGcnk=", + "requires": { + "find-up": "2.1.0", + "load-json-file": "2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "2.0.0" + } + } + } + }, + "pkg-config": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", + "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", + "requires": { + "debug-log": "1.0.1", + "find-root": "1.1.0", + "xtend": "4.0.1" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "requires": { + "find-up": "1.1.2" + } + }, + "pkg-up": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", + "requires": { + "find-up": "1.1.2" + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", @@ -1237,6 +2408,11 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=" + }, "proxy-middleware": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz", @@ -1333,6 +2509,34 @@ "set-immediate-shim": "1.0.1" } }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "mute-stream": "0.0.5" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + } + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "1.5.0" + } + }, "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", @@ -1373,16 +2577,90 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "7.1.2" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "requires": { + "once": "1.4.0" + } + }, + "run-parallel": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.6.tgz", + "integrity": "sha1-KQA8miFj4B4tLfyQV18sbB1hoDk=" + }, "rx": { "version": "2.3.24", "resolved": "https://registry.npmjs.org/rx/-/rx-2.3.24.tgz", "integrity": "sha1-FPlQpCF9fjXapxu8vljv9o6ksrc=" }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=" + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, + "semistandard": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/semistandard/-/semistandard-11.0.0.tgz", + "integrity": "sha1-0tn8isOT3iExIZXgBuUMiGE5HEc=", + "requires": { + "eslint": "3.19.0", + "eslint-config-semistandard": "11.0.0", + "eslint-config-standard": "10.2.1", + "eslint-config-standard-jsx": "4.0.1", + "eslint-plugin-import": "2.2.0", + "eslint-plugin-node": "4.2.3", + "eslint-plugin-promise": "3.5.0", + "eslint-plugin-react": "6.10.3", + "eslint-plugin-standard": "3.0.1", + "standard-engine": "7.0.0" + } + }, "semver": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", @@ -1483,11 +2761,26 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "requires": { + "glob": "7.1.2", + "interpret": "1.1.0", + "rechoir": "0.6.2" + } + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=" + }, "spawn-command": { "version": "0.0.2-1", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", @@ -1506,6 +2799,17 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "standard-engine": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz", + "integrity": "sha1-67d7nI/CyBZf+jU72Rug3/Qa9pA=", + "requires": { + "deglob": "2.1.0", + "get-stdin": "5.0.1", + "minimist": "1.2.0", + "pkg-conf": "2.0.0" + } + }, "statuses": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", @@ -1559,6 +2863,11 @@ "ansi-regex": "0.2.1" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -1577,6 +2886,64 @@ "has-flag": "1.0.0" } }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "requires": { + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.4", + "slice-ansi": "0.0.4", + "string-width": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, "term-size": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", @@ -1585,6 +2952,11 @@ "execa": "0.7.0" } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -1608,6 +2980,19 @@ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==" }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "uc.micro": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.3.tgz", @@ -1618,6 +3003,11 @@ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-0.0.3.tgz", "integrity": "sha1-7Mo6A+VrmvFzhbqsgSrIO5lKli8=" }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, "unique-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", @@ -1703,6 +3093,14 @@ "prepend-http": "1.0.4" } }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "requires": { + "os-homedir": "1.0.2" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -1786,6 +3184,24 @@ } } }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "requires": { + "mkdirp": "0.5.1" + } + }, "write-file-atomic": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", @@ -1801,6 +3217,11 @@ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", diff --git a/package.json b/package.json index d4e46f083..a616c02d0 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "fs-extra": "^4.0.2", "live-server": "^1.2.0", "markdown-it": "^8.4.0", - "nodemon": "^1.12.1" + "nodemon": "^1.12.1", + "semistandard": "^11.0.0" }, "name": "30-seconds-of-code", "description": "A collection of useful Javascript snippets.", @@ -13,6 +14,7 @@ "devDependencies": {}, "scripts": { "build-list": "node ./scripts/builder.js", + "lint": "node ./scripts/lintSnippet.js", "start": "concurrently --kill-others \"nodemon -e js,md -i README.md -x \\\"npm run build-list\\\"\" \"live-server ./build\"" }, "repository": { diff --git a/scripts/builder.js b/scripts/builder.js index b3305147a..b9a5d5bc8 100644 --- a/scripts/builder.js +++ b/scripts/builder.js @@ -6,6 +6,8 @@ var staticPartsPath = './static-parts'; var snippets = {}, startPart = '', endPart = '', output = ''; +console.time('Builder'); + try { var snippetFilenames = fs.readdirSync(snippetsPath); snippetFilenames.sort((a, b) => { @@ -51,3 +53,5 @@ catch (err){ console.log('Error during README generation: '+err); process.exit(1); } + +console.timeEnd('Builder'); diff --git a/scripts/lintSnippet.js b/scripts/lintSnippet.js new file mode 100644 index 000000000..a53686ee5 --- /dev/null +++ b/scripts/lintSnippet.js @@ -0,0 +1,31 @@ +var fs = require('fs-extra'); +var cp = require('child_process'); +var path = require('path'); + +var snippetsPath = './snippets'; +var snippetFilename = ''; + +console.time('Linter'); + +if(process.argv.length < 3){ + console.log('Please specify the filename of a snippet to be linted.'); + console.log('Example usage: npm run lint "snippet-file.md"'); + process.exit(0); +} +else { + snippetFilename = process.argv[2]; + let snippetData = fs.readFileSync(path.join(snippetsPath,snippetFilename),'utf8'); + try { + let originalCode = snippetData.slice(snippetData.indexOf('```js')+5,snippetData.lastIndexOf('```')); + fs.writeFileSync('currentSnippet.js',`${originalCode}`); + cp.exec('semistandard "currentSnippet.js" --fix',{},(error, stdOut, stdErr) => { + let lintedCode = fs.readFileSync('currentSnippet.js','utf8'); + fs.writeFile(path.join(snippetsPath,snippetFilename), `${snippetData.slice(0, snippetData.indexOf('```js')+5)+lintedCode+'```\n'}`); + console.timeEnd('Linter'); + }); + } + catch (err){ + console.log('Error during snippet loading: '+err); + process.exit(1); + } +} diff --git a/semi-snippets.js b/semi-snippets.js new file mode 100644 index 000000000..c35e9d6b8 --- /dev/null +++ b/semi-snippets.js @@ -0,0 +1,242 @@ + +const anagrams = str => { + if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; + return str.split('').reduce((acc, letter, i) => + acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)), []); +}; +// anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] + +const average = arr => + arr.reduce((acc, val) => acc + val, 0) / arr.length; +// average([1,2,3]) -> 2 + +const bottomVisible = _ => + document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; +// bottomVisible() -> true + +const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); +// capitalizeEveryWord('hello world!') -> 'Hello World!' + +const capitalize = (str, lowerRest = false) => + str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); +// capitalize('myName', true) -> 'Myname' + +const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); }; +/* +chainAsync([ + next => { console.log('0 seconds'); setTimeout(next, 1000); }, + next => { console.log('1 second'); setTimeout(next, 1000); }, + next => { console.log('2 seconds'); } +]) +*/ + +const palindrome = str => + str.toLowerCase().replace(/[\W_]/g, '').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g, ''); +// palindrome('taco cat') -> true + +const chunk = (arr, size) => + Array.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); +// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] + +const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); +// countOccurrences([1,1,2,1,2,3], 1) -> 3 + +const currentUrl = _ => window.location.href; +// currentUrl() -> 'https://google.com' + +const curry = (f, arity = f.length, next) => + (next = prevArgs => + nextArg => { + const args = [ ...prevArgs, nextArg ]; + return args.length >= arity ? f(...args) : next(args); + } + )([]); +// curry(Math.pow)(2)(10) -> 1024 +// curry(Math.min, 3)(10)(50)(2) -> 2 + +const deepFlatten = arr => + arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []); +// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] + +const difference = (arr, values) => arr.filter(v => !values.includes(v)); +// difference([1,2,3], [1,2]) -> [3] + +const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); +// distance(1,1, 2,3) -> 2.23606797749979 + +const isDivisible = (dividend, divisor) => dividend % divisor === 0; +// isDivisible(6,3) -> true + +const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +// escapeRegExp('(test)') -> \\(test\\) + +const isEven = num => Math.abs(num) % 2 === 0; +// isEven(3) -> false + +const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); +// factorial(6) -> 720 + +const fibonacci = n => + Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []); +// fibonacci(5) -> [0,1,1,2,3] + +const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); +// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] + +const flatten = arr => arr.reduce((a, v) => a.concat(v), []); +// flatten([1,[2],3,4]) -> [1,2,3,4] + +const arrayMax = arr => Math.max(...arr); +// arrayMax([10, 1, 5]) -> 10 + +const arrayMin = arr => Math.min(...arr); +// arrayMin([10, 1, 5]) -> 1 + +const getType = v => + v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); +// getType(new Set([1,2,3])) -> "set" + +const getScrollPos = (el = window) => + ({x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, + y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop}); +// getScrollPos() -> {x: 0, y: 200} + +const gcd = (x, y) => !y ? x : gcd(y, x % y); +// gcd (8, 36) -> 4 + +const hammingDistance = (num1, num2) => + ((num1 ^ num2).toString(2).match(/1/g) || '').length; +// hammingDistance(2,3) -> 1 + +const head = arr => arr[0]; +// head([1,2,3]) -> 1 + +const initial = arr => arr.slice(0, -1); +// initial([1,2,3]) -> [1,2] + +const initializeArrayRange = (end, start = 0) => + Array.apply(null, Array(end - start)).map((v, i) => i + start); +// initializeArrayRange(5) -> [0,1,2,3,4] + +const initializeArray = (n, value = 0) => Array(n).fill(value); +// initializeArray(5, 2) -> [2,2,2,2,2] + +const last = arr => arr.slice(-1)[0]; +// last([1,2,3]) -> 3 + +const timeTaken = callback => { + const t0 = performance.now(), r = callback(); + console.log(performance.now() - t0); + return r; +}; +// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) + +const median = arr => { + const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +}; +// median([5,6,50,1,-5]) -> 5 +// median([0,10,-2,7]) -> 3.5 + +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); +// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} + +const percentile = (arr, val) => + 100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; +// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 + +const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg); +// pipe(btoa, x => x.toUpperCase())("Test") -> "VGVZDA==" + +const powerset = arr => + arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); +// powerset([1,2]) -> [[], [1], [2], [2,1]] + +const promisify = func => + (...args) => + new Promise((resolve, reject) => + func(...args, (err, result) => + err ? reject(err) : resolve(result)) + ); +// const delay = promisify((d, cb) => setTimeout(cb, d)) +// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s + +const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; +// randomIntegerInRange(0, 5) -> 2 + +const randomInRange = (min, max) => Math.random() * (max - min) + min; +// randomInRange(2,10) -> 6.0211363285087005 + +const randomizeOrder = arr => arr.sort((a, b) => Math.random() >= 0.5 ? -1 : 1); +// randomizeOrder([1,2,3]) -> [1,3,2] + +const redirect = (url, asLink = true) => + asLink ? window.location.href = url : window.location.replace(url); +// redirect('https://google.com') + +const reverseString = str => [...str].reverse().join(''); +// reverseString('foobar') -> 'raboof' + +const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); +// rgbToHex(255, 165, 1) -> 'ffa501' + +const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); +// const delay = (d) => new Promise(r => setTimeout(r, d)) +// series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete + +const scrollToTop = _ => { + const c = document.documentElement.scrollTop || document.body.scrollTop; + if (c > 0) { + window.requestAnimationFrame(scrollToTop); + window.scrollTo(0, c - c / 8); + } +}; +// scrollToTop() + +const shuffle = arr => { + let r = arr.map(Math.random); + return arr.sort((a, b) => r[a] - r[b]); +}; +// shuffle([1,2,3]) -> [2, 1, 3] + +const similarity = (arr, values) => arr.filter(v => values.includes(v)); +// similarity([1,2,3], [1,2,4]) -> [1,2] + +const sortCharactersInString = str => + str.split('').sort((a, b) => a.localeCompare(b)).join(''); +// sortCharactersInString('cabbage') -> 'aabbceg' + +const sum = arr => arr.reduce((acc, val) => acc + val, 0); +// sum([1,2,3,4]) -> 10 + +[varA, varB] = [varB, varA]; +// [x, y] = [y, x] + +const tail = arr => arr.length > 1 ? arr.slice(1) : arr; +// tail([1,2,3]) -> [2,3] +// tail([1]) -> [1] + +const truncate = (str, num) => + str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; +// truncate('boomerang', 7) -> 'boom...' + +const unique = arr => [...new Set(arr)]; +// unique([1,2,2,3,4,4,5]) -> [1,2,3,4,5] + +const getUrlParameters = url => + url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} + ); +// getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} + +const uuid = _ => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => + (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) + ); +// uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' + +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); +// validateNumber('10') -> true + +const valueOrDefault = (value, d) => value || d; +// valueOrDefault(NaN, 30) -> 30 diff --git a/snippets.js b/snippets.js new file mode 100644 index 000000000..d754bf389 --- /dev/null +++ b/snippets.js @@ -0,0 +1,302 @@ + +const anagrams = str => { + if(str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; + return str.split('').reduce( (acc, letter, i) => + acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => letter + val )), []); +} +// anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] + + +const average = arr => + arr.reduce( (acc , val) => acc + val, 0) / arr.length; +// average([1,2,3]) -> 2 + + +const bottomVisible = _ => + document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; +// bottomVisible() -> true + + +const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); +// capitalizeEveryWord('hello world!') -> 'Hello World!' + + +const capitalize = (str, lowerRest = false) => + str.slice(0, 1).toUpperCase() + (lowerRest? str.slice(1).toLowerCase() : str.slice(1)); +// capitalize('myName', true) -> 'Myname' + + +const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); } +/* +chainAsync([ + next => { console.log('0 seconds'); setTimeout(next, 1000); }, + next => { console.log('1 second'); setTimeout(next, 1000); }, + next => { console.log('2 seconds'); } +]) +*/ + + +const palindrome = str => + str.toLowerCase().replace(/[\W_]/g,'').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g,''); +// palindrome('taco cat') -> true + + +const chunk = (arr, size) => + Array.apply(null, {length: Math.ceil(arr.length/size)}).map((v, i) => arr.slice(i*size, i*size+size)); +// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] + + +const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); +// countOccurrences([1,1,2,1,2,3], 1) -> 3 + + +const currentUrl = _ => window.location.href; +// currentUrl() -> 'https://google.com' + + +const curry = (f, arity = f.length, next) => + (next = prevArgs => + nextArg => { + const args = [ ...prevArgs, nextArg ]; + return args.length >= arity ? f(...args) : next(args); + } + )([]); +// curry(Math.pow)(2)(10) -> 1024 +// curry(Math.min, 3)(10)(50)(2) -> 2 + + +const deepFlatten = arr => + arr.reduce( (a, v) => a.concat( Array.isArray(v) ? deepFlatten(v) : v ), []); +// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] + + +const difference = (arr, values) => arr.filter(v => !values.includes(v)); +// difference([1,2,3], [1,2]) -> [3] + + +const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); +// distance(1,1, 2,3) -> 2.23606797749979 + + +const isDivisible = (dividend, divisor) => dividend % divisor === 0; +// isDivisible(6,3) -> true + + +const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +// escapeRegExp('(test)') -> \\(test\\) + + +const isEven = num => Math.abs(num) % 2 === 0; +// isEven(3) -> false + + +const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); +// factorial(6) -> 720 + + +const fibonacci = n => + Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),[]); +// fibonacci(5) -> [0,1,1,2,3] + + +const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); +// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] + + +const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); +// flatten([1,[2],3,4]) -> [1,2,3,4] + + +const arrayMax = arr => Math.max(...arr); +// arrayMax([10, 1, 5]) -> 10 + + +const arrayMin = arr => Math.min(...arr); +// arrayMin([10, 1, 5]) -> 1 + + +const getType = v => + v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); +// getType(new Set([1,2,3])) -> "set" + + +const getScrollPos = (el = window) => + ( {x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, + y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop} ); +// getScrollPos() -> {x: 0, y: 200} + + +const gcd = (x , y) => !y ? x : gcd(y, x % y); +// gcd (8, 36) -> 4 + + +const hammingDistance = (num1, num2) => + ((num1^num2).toString(2).match(/1/g) || '').length; +// hammingDistance(2,3) -> 1 + + +const head = arr => arr[0]; +// head([1,2,3]) -> 1 + + +const initial = arr => arr.slice(0,-1); +// initial([1,2,3]) -> [1,2] + + +const initializeArrayRange = (end, start = 0) => + Array.apply(null, Array(end-start)).map( (v,i) => i + start ); +// initializeArrayRange(5) -> [0,1,2,3,4] + + +const initializeArray = (n, value = 0) => Array(n).fill(value); +// initializeArray(5, 2) -> [2,2,2,2,2] + + +const last = arr => arr.slice(-1)[0]; +// last([1,2,3]) -> 3 + + +const timeTaken = callback => { + const t0 = performance.now(), r = callback(); + console.log(performance.now() - t0); + return r; +} +// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) + + +const median = arr => { + const mid = Math.floor(arr.length / 2), nums = arr.sort((a,b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; +} +// median([5,6,50,1,-5]) -> 5 +// median([0,10,-2,7]) -> 3.5 + + +const objectFromPairs = arr => arr.reduce((a,v) => (a[v[0]] = v[1], a), {}); +// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} + + +const percentile = (arr, val) => + 100 * arr.reduce((acc,v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; +// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 + + +const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg); +// pipe(btoa, x => x.toUpperCase())("Test") -> "VGVZDA==" + + +const powerset = arr => + arr.reduce( (a,v) => a.concat(a.map( r => [v].concat(r) )), [[]]); +// powerset([1,2]) -> [[], [1], [2], [2,1]] + + +const promisify = func => + (...args) => + new Promise((resolve, reject) => + func(...args, (err, result) => + err ? reject(err) : resolve(result)) + ); +// const delay = promisify((d, cb) => setTimeout(cb, d)) +// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s + + +const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; +// randomIntegerInRange(0, 5) -> 2 + + +const randomInRange = (min, max) => Math.random() * (max - min) + min; +// randomInRange(2,10) -> 6.0211363285087005 + + +const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); +// randomizeOrder([1,2,3]) -> [1,3,2] + + +const redirect = (url, asLink = true) => + asLink ? window.location.href = url : window.location.replace(url); +// redirect('https://google.com') + + +const reverseString = str => [...str].reverse().join(''); +// reverseString('foobar') -> 'raboof' + + +const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); +// rgbToHex(255, 165, 1) -> 'ffa501' + + +const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); +// const delay = (d) => new Promise(r => setTimeout(r, d)) +// series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete + + +const scrollToTop = _ => { + const c = document.documentElement.scrollTop || document.body.scrollTop; + if(c > 0) { + window.requestAnimationFrame(scrollToTop); + window.scrollTo(0, c - c/8); + } +} +// scrollToTop() + + +const shuffle = arr => { + let r = arr.map(Math.random); + return arr.sort((a,b) => r[a] - r[b]); +} +// shuffle([1,2,3]) -> [2, 1, 3] + + +const similarity = (arr, values) => arr.filter(v => values.includes(v)); +// similarity([1,2,3], [1,2,4]) -> [1,2] + + +const sortCharactersInString = str => + str.split('').sort( (a,b) => a.localeCompare(b) ).join(''); +// sortCharactersInString('cabbage') -> 'aabbceg' + + +const sum = arr => arr.reduce( (acc , val) => acc + val, 0); +// sum([1,2,3,4]) -> 10 + + +[varA, varB] = [varB, varA]; +// [x, y] = [y, x] + + +const tail = arr => arr.length > 1 ? arr.slice(1) : arr; +// tail([1,2,3]) -> [2,3] +// tail([1]) -> [1] + + +const truncate = (str, num) => + str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; +// truncate('boomerang', 7) -> 'boom...' + + +const unique = arr => [...new Set(arr)]; +// unique([1,2,2,3,4,4,5]) -> [1,2,3,4,5] + + +const getUrlParameters = url => + url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')+1), a), {} + ); +// getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} + + +const uuid = _ => + ( [1e7]+-1e3+-4e3+-8e3+-1e11 ).replace( /[018]/g, c => + (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) + ); +// uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' + + +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); +// validateNumber('10') -> true + + +const valueOrDefault = (value, d) => value || d; +// valueOrDefault(NaN, 30) -> 30 + + diff --git a/snippets/URL-parameters.md b/snippets/URL-parameters.md index c5a316b76..742e7ffbd 100644 --- a/snippets/URL-parameters.md +++ b/snippets/URL-parameters.md @@ -6,7 +6,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => url.match(/([^?=&]+)(=([^&]*))?/g).reduce( - (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')+1), a), {} + (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} ``` diff --git a/snippets/UUID-generator.md b/snippets/UUID-generator.md index b7860cf64..01d4e27ac 100644 --- a/snippets/UUID-generator.md +++ b/snippets/UUID-generator.md @@ -4,7 +4,7 @@ Use `crypto` API to generate a UUID, compliant with [RFC4122](https://www.ietf.o ```js const uuid = _ => - ( [1e7]+-1e3+-4e3+-8e3+-1e11 ).replace( /[018]/g, c => + ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ); // uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' diff --git a/snippets/anagrams-of-string-(with-duplicates).md b/snippets/anagrams-of-string-(with-duplicates).md index 7e1d613b6..bbc2e3dfb 100644 --- a/snippets/anagrams-of-string-(with-duplicates).md +++ b/snippets/anagrams-of-string-(with-duplicates).md @@ -7,9 +7,9 @@ Base cases are for string `length` equal to `2` or `1`. ```js const anagrams = str => { - if(str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; - return str.split('').reduce( (acc, letter, i) => - acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => letter + val )), []); -} + if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; + return str.split('').reduce((acc, letter, i) => + acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)), []); +}; // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` diff --git a/snippets/average-of-array-of-numbers.md b/snippets/average-of-array-of-numbers.md index 8d9aaf1cd..73ae7bc39 100644 --- a/snippets/average-of-array-of-numbers.md +++ b/snippets/average-of-array-of-numbers.md @@ -3,7 +3,6 @@ Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. ```js -const average = arr => - arr.reduce( (acc , val) => acc + val, 0) / arr.length; +const average = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length; // average([1,2,3]) -> 2 ``` diff --git a/snippets/bottom-visible.md b/snippets/bottom-visible.md index 9045c6bff..b94ac773a 100644 --- a/snippets/bottom-visible.md +++ b/snippets/bottom-visible.md @@ -3,7 +3,7 @@ Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible. ```js -const bottomVisible = _ => +const bottomVisible = _ => document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; // bottomVisible() -> true ``` diff --git a/snippets/capitalize-first-letter.md b/snippets/capitalize-first-letter.md index 99be77927..61f73b6a7 100644 --- a/snippets/capitalize-first-letter.md +++ b/snippets/capitalize-first-letter.md @@ -5,6 +5,6 @@ Omit the `lowerRest` parameter to keep the rest of the string intact, or set it ```js const capitalize = (str, lowerRest = false) => - str.slice(0, 1).toUpperCase() + (lowerRest? str.slice(1).toLowerCase() : str.slice(1)); + str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); // capitalize('myName', true) -> 'Myname' ``` diff --git a/snippets/chain-asynchronous-functions.md b/snippets/chain-asynchronous-functions.md index 6c6118b3c..8aec5d186 100644 --- a/snippets/chain-asynchronous-functions.md +++ b/snippets/chain-asynchronous-functions.md @@ -3,7 +3,7 @@ Loop through an array of functions containing asynchronous events, calling `next` when each asynchronous event has completed. ```js -const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); } +const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); }; /* chainAsync([ next => { console.log('0 seconds'); setTimeout(next, 1000); }, diff --git a/snippets/chunk-array.md b/snippets/chunk-array.md index 8f92499a2..de6c5a568 100644 --- a/snippets/chunk-array.md +++ b/snippets/chunk-array.md @@ -6,6 +6,6 @@ If the original array can't be split evenly, the final chunk will contain the re ```js const chunk = (arr, size) => - Array.apply(null, {length: Math.ceil(arr.length/size)}).map((v, i) => arr.slice(i*size, i*size+size)); + Array.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` diff --git a/snippets/deep-flatten-array.md b/snippets/deep-flatten-array.md index 397d62241..c350d848c 100644 --- a/snippets/deep-flatten-array.md +++ b/snippets/deep-flatten-array.md @@ -5,6 +5,6 @@ Use `Array.reduce()` to get all elements that are not arrays, flatten each eleme ```js const deepFlatten = arr => - arr.reduce( (a, v) => a.concat( Array.isArray(v) ? deepFlatten(v) : v ), []); + arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []); // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] ``` diff --git a/snippets/fibonacci-array-generator.md b/snippets/fibonacci-array-generator.md index 0255e8875..7f0d4c7d2 100644 --- a/snippets/fibonacci-array-generator.md +++ b/snippets/fibonacci-array-generator.md @@ -4,7 +4,7 @@ Create an empty array of the specific length, initializing the first two values Use `Array.reduce()` to add values into the array, using the sum of the last two values, except for the first two. ```js -const fibonacci = n => - Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),[]); +const fibonacci = n => + Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []); // fibonacci(5) -> [0,1,1,2,3] ``` diff --git a/snippets/flatten-array.md b/snippets/flatten-array.md index 224060d02..d23f24611 100644 --- a/snippets/flatten-array.md +++ b/snippets/flatten-array.md @@ -3,6 +3,6 @@ Use `Array.reduce()` to get all elements inside the array and `concat()` to flatten them. ```js -const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); +const flatten = arr => arr.reduce((a, v) => a.concat(v), []); // flatten([1,[2],3,4]) -> [1,2,3,4] ``` diff --git a/snippets/get-native-type-of-value.md b/snippets/get-native-type-of-value.md index d2ded3f83..9e043a83e 100644 --- a/snippets/get-native-type-of-value.md +++ b/snippets/get-native-type-of-value.md @@ -4,6 +4,6 @@ Returns lower-cased constructor name of value, "undefined" or "null" if value is ```js const getType = v => - v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); + v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); // getType(new Set([1,2,3])) -> "set" ``` diff --git a/snippets/get-scroll-position.md b/snippets/get-scroll-position.md index 7e367168f..4f134a9fb 100644 --- a/snippets/get-scroll-position.md +++ b/snippets/get-scroll-position.md @@ -5,7 +5,7 @@ You can omit `el` to use a default value of `window`. ```js const getScrollPos = (el = window) => - ( {x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, - y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop} ); + ({x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, + y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop}); // getScrollPos() -> {x: 0, y: 200} ``` diff --git a/snippets/greatest-common-divisor-(GCD).md b/snippets/greatest-common-divisor-(GCD).md index 38b5603ca..d1025a029 100644 --- a/snippets/greatest-common-divisor-(GCD).md +++ b/snippets/greatest-common-divisor-(GCD).md @@ -5,6 +5,6 @@ Base case is when `y` equals `0`. In this case, return `x`. Otherwise, return the GCD of `y` and the remainder of the division `x/y`. ```js -const gcd = (x , y) => !y ? x : gcd(y, x % y); +const gcd = (x, y) => !y ? x : gcd(y, x % y); // gcd (8, 36) -> 4 ``` diff --git a/snippets/hamming-distance.md b/snippets/hamming-distance.md index 5b47db022..e524408a8 100644 --- a/snippets/hamming-distance.md +++ b/snippets/hamming-distance.md @@ -5,6 +5,6 @@ Count and return the number of `1`s in the string, using `match(/1/g)`. ```js const hammingDistance = (num1, num2) => - ((num1^num2).toString(2).match(/1/g) || '').length; + ((num1 ^ num2).toString(2).match(/1/g) || '').length; // hammingDistance(2,3) -> 1 ``` diff --git a/snippets/initial-of-list.md b/snippets/initial-of-list.md index 77ea3e8f7..a222f2306 100644 --- a/snippets/initial-of-list.md +++ b/snippets/initial-of-list.md @@ -3,6 +3,6 @@ Return `arr.slice(0,-1)`. ```js -const initial = arr => arr.slice(0,-1); +const initial = arr => arr.slice(0, -1); // initial([1,2,3]) -> [1,2] ``` diff --git a/snippets/initialize-array-with-range.md b/snippets/initialize-array-with-range.md index 03de99eb2..def23fb9c 100644 --- a/snippets/initialize-array-with-range.md +++ b/snippets/initialize-array-with-range.md @@ -5,6 +5,6 @@ You can omit `start` to use a default value of `0`. ```js const initializeArrayRange = (end, start = 0) => - Array.apply(null, Array(end-start)).map( (v,i) => i + start ); + Array.apply(null, Array(end - start)).map((v, i) => i + start); // initializeArrayRange(5) -> [0,1,2,3,4] ``` diff --git a/snippets/measure-time-taken-by-function.md b/snippets/measure-time-taken-by-function.md index 73d32141e..44e099d7e 100644 --- a/snippets/measure-time-taken-by-function.md +++ b/snippets/measure-time-taken-by-function.md @@ -8,6 +8,6 @@ const timeTaken = callback => { const t0 = performance.now(), r = callback(); console.log(performance.now() - t0); return r; -} +}; // timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) ``` diff --git a/snippets/median-of-array-of-numbers.md b/snippets/median-of-array-of-numbers.md index 3a675a545..8113d51c6 100644 --- a/snippets/median-of-array-of-numbers.md +++ b/snippets/median-of-array-of-numbers.md @@ -5,9 +5,9 @@ Return the number at the midpoint if `length` is odd, otherwise the average of t ```js const median = arr => { - const mid = Math.floor(arr.length / 2), nums = arr.sort((a,b) => a - b); + const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; -} +}; // median([5,6,50,1,-5]) -> 5 // median([0,10,-2,7]) -> 3.5 ``` diff --git a/snippets/object-from-key-value-pairs.md b/snippets/object-from-key-value-pairs.md index df01da0ba..cbb545c06 100644 --- a/snippets/object-from-key-value-pairs.md +++ b/snippets/object-from-key-value-pairs.md @@ -3,6 +3,6 @@ Use `Array.reduce()` to create and combine key-value pairs. ```js -const objectFromPairs = arr => arr.reduce((a,v) => (a[v[0]] = v[1], a), {}); +const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); // objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} ``` diff --git a/snippets/powerset.md b/snippets/powerset.md index 62ec96655..73b71b645 100644 --- a/snippets/powerset.md +++ b/snippets/powerset.md @@ -4,6 +4,6 @@ Use `Array.reduce()` combined with `Array.map()` to iterate over elements and co ```js const powerset = arr => - arr.reduce( (a,v) => a.concat(a.map( r => [v].concat(r) )), [[]]); + arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); // powerset([1,2]) -> [[], [1], [2], [2,1]] ``` diff --git a/snippets/randomize-order-of-array.md b/snippets/randomize-order-of-array.md index d65aaf444..456a00607 100644 --- a/snippets/randomize-order-of-array.md +++ b/snippets/randomize-order-of-array.md @@ -3,6 +3,6 @@ Use `Array.sort()` to reorder elements, utilizing `Math.random()` to randomize the sorting. ```js -const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); +const randomizeOrder = arr => arr.sort((a, b) => Math.random() >= 0.5 ? -1 : 1); // randomizeOrder([1,2,3]) -> [1,3,2] ``` diff --git a/snippets/scroll-to-top.md b/snippets/scroll-to-top.md index 7a813429a..6c82190a4 100644 --- a/snippets/scroll-to-top.md +++ b/snippets/scroll-to-top.md @@ -6,10 +6,10 @@ Scroll by a fraction of the distance from top. Use `window.requestAnimationFrame ```js const scrollToTop = _ => { const c = document.documentElement.scrollTop || document.body.scrollTop; - if(c > 0) { + if (c > 0) { window.requestAnimationFrame(scrollToTop); - window.scrollTo(0, c - c/8); + window.scrollTo(0, c - c / 8); } -} +}; // scrollToTop() ``` diff --git a/snippets/shuffle-array-values.md b/snippets/shuffle-array-values.md index a140bd647..ab3698a31 100644 --- a/snippets/shuffle-array-values.md +++ b/snippets/shuffle-array-values.md @@ -6,7 +6,7 @@ Use `Array.sort()` to sort the elements of the original array based on the rando ```js const shuffle = arr => { let r = arr.map(Math.random); - return arr.sort((a,b) => r[a] - r[b]); -} + return arr.sort((a, b) => r[a] - r[b]); +}; // shuffle([1,2,3]) -> [2, 1, 3] ``` diff --git a/snippets/sort-characters-in-string-(alphabetical).md b/snippets/sort-characters-in-string-(alphabetical).md index 7ed73cb14..9cf37ad77 100644 --- a/snippets/sort-characters-in-string-(alphabetical).md +++ b/snippets/sort-characters-in-string-(alphabetical).md @@ -4,6 +4,6 @@ Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, ```js const sortCharactersInString = str => - str.split('').sort( (a,b) => a.localeCompare(b) ).join(''); + str.split('').sort((a, b) => a.localeCompare(b)).join(''); // sortCharactersInString('cabbage') -> 'aabbceg' ``` diff --git a/snippets/sum-of-array-of-numbers.md b/snippets/sum-of-array-of-numbers.md index 939106cc1..9729eb474 100644 --- a/snippets/sum-of-array-of-numbers.md +++ b/snippets/sum-of-array-of-numbers.md @@ -3,6 +3,6 @@ Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. ```js -const sum = arr => arr.reduce( (acc , val) => acc + val, 0); +const sum = arr => arr.reduce((acc, val) => acc + val, 0); // sum([1,2,3,4]) -> 10 ``` diff --git a/snippets/truncate-a-string.md b/snippets/truncate-a-string.md index 556667781..a33ac6367 100644 --- a/snippets/truncate-a-string.md +++ b/snippets/truncate-a-string.md @@ -5,6 +5,6 @@ Return the string truncated to the desired length, with `...` appended to the en ```js const truncate = (str, num) => - str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; + str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; // truncate('boomerang', 7) -> 'boom...' ``` From 7bee9e146e9e1d8b9c3d787a522c3ad450158d1e Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Wed, 13 Dec 2017 23:06:54 +0100 Subject: [PATCH 09/46] Add "Object to key-value pairs" --- README.md | 8 ++++++++ snippets/object-to-key-value-pairs.md | 6 ++++++ 2 files changed, 14 insertions(+) create mode 100644 snippets/object-to-key-value-pairs.md diff --git a/README.md b/README.md index b77013e78..d54c7f2d9 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ * [Measure time taken by function](#measure-time-taken-by-function) * [Median of array of numbers](#median-of-array-of-numbers) * [Object from key value pairs](#object-from-key-value-pairs) +* [Object to key value pairs](#object-to-key-value-pairs) * [Percentile](#percentile) * [Pipe](#pipe) * [Powerset](#powerset) @@ -444,6 +445,13 @@ const objectFromPairs = arr => arr.reduce((a,v) => (a[v[0]] = v[1], a), {}); // objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} ``` +### Object to key-value pairs + +```js +const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); +// objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) +``` + ### Percentile Use `Array.reduce()` to calculate how many numbers are below the value and how many are the same value and diff --git a/snippets/object-to-key-value-pairs.md b/snippets/object-to-key-value-pairs.md new file mode 100644 index 000000000..78fd63811 --- /dev/null +++ b/snippets/object-to-key-value-pairs.md @@ -0,0 +1,6 @@ +### Object to key-value pairs + +```js +const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); +// objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) +``` From a4a7eb275af0c74dd8fe28b4147391751ec68a65 Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Wed, 13 Dec 2017 23:40:27 +0100 Subject: [PATCH 10/46] Add set operations. Union, intersect and difference --- README.md | 40 ++++++++++++++++++++------- snippets/array-difference.md | 8 ++++++ snippets/array-intersection.md | 8 ++++++ snippets/array-union.md | 8 ++++++ snippets/difference-between-arrays.md | 8 ------ 5 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 snippets/array-difference.md create mode 100644 snippets/array-intersection.md create mode 100644 snippets/array-union.md delete mode 100644 snippets/difference-between-arrays.md diff --git a/README.md b/README.md index b77013e78..c66371a79 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,9 @@ ## Contents * [Anagrams of string (with duplicates)](#anagrams-of-string-with-duplicates) +* [Array difference](#array-difference) +* [Array intersection](#array-intersection) +* [Array union](#array-union) * [Average of array of numbers](#average-of-array-of-numbers) * [Bottom visible](#bottom-visible) * [Capitalize first letter of every word](#capitalize-first-letter-of-every-word) @@ -21,7 +24,6 @@ * [Current URL](#current-url) * [Curry](#curry) * [Deep flatten array](#deep-flatten-array) -* [Difference between arrays](#difference-between-arrays) * [Distance between two points](#distance-between-two-points) * [Divisible by number](#divisible-by-number) * [Escape regular expression](#escape-regular-expression) @@ -85,6 +87,33 @@ const anagrams = str => { // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` +### Array difference (complement) + +Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. + +```js +const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); } +// difference([1,2,3], [1,2]) -> [3] +``` + +### Array intersection (Common values between two arrays) + +Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. + +```js +const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); } +// intersection([1,2,3], [4,3,2]) -> [2,3] +``` + +### Array union + +Create a `Set` with all values of `a` and `b` and convert to an array. + +```js +const union = (a, b) => Array.from(new Set([...a, ...b])) +// union([1,2,3], [4,3,2]) -> [1,2,3,4] +``` + ### Average of array of numbers Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. @@ -211,15 +240,6 @@ const deepFlatten = arr => // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] ``` -### Difference between arrays - -Use `filter()` to remove values that are part of `values`, determined using `includes()`. - -```js -const difference = (arr, values) => arr.filter(v => !values.includes(v)); -// difference([1,2,3], [1,2]) -> [3] -``` - ### Distance between two points Use `Math.hypot()` to calculate the Euclidean distance between two points. diff --git a/snippets/array-difference.md b/snippets/array-difference.md new file mode 100644 index 000000000..74e518f5c --- /dev/null +++ b/snippets/array-difference.md @@ -0,0 +1,8 @@ +### Array difference (complement) + +Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. + +```js +const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); } +// difference([1,2,3], [1,2]) -> [3] +``` diff --git a/snippets/array-intersection.md b/snippets/array-intersection.md new file mode 100644 index 000000000..909c4312d --- /dev/null +++ b/snippets/array-intersection.md @@ -0,0 +1,8 @@ +### Array intersection (Common values between two arrays) + +Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. + +```js +const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); } +// intersection([1,2,3], [4,3,2]) -> [2,3] +``` diff --git a/snippets/array-union.md b/snippets/array-union.md new file mode 100644 index 000000000..b417dcce7 --- /dev/null +++ b/snippets/array-union.md @@ -0,0 +1,8 @@ +### Array union + +Create a `Set` with all values of `a` and `b` and convert to an array. + +```js +const union = (a, b) => Array.from(new Set([...a, ...b])) +// union([1,2,3], [4,3,2]) -> [1,2,3,4] +``` diff --git a/snippets/difference-between-arrays.md b/snippets/difference-between-arrays.md deleted file mode 100644 index 1fb172dab..000000000 --- a/snippets/difference-between-arrays.md +++ /dev/null @@ -1,8 +0,0 @@ -### Difference between arrays - -Use `filter()` to remove values that are part of `values`, determined using `includes()`. - -```js -const difference = (arr, values) => arr.filter(v => !values.includes(v)); -// difference([1,2,3], [1,2]) -> [3] -``` From 13c4782c69accfdfe7b8b7f597f6c87f4770e4c8 Mon Sep 17 00:00:00 2001 From: King Date: Wed, 13 Dec 2017 17:41:24 -0500 Subject: [PATCH 11/46] update pick.md -> oneline & simpler solution --- snippets/pick.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/snippets/pick.md b/snippets/pick.md index 5523e1fe5..c3b5cd2f2 100644 --- a/snippets/pick.md +++ b/snippets/pick.md @@ -1,18 +1,9 @@ ### Pick -Use `Objexts.keys()` to convert given object to an iterable arr of keys. -Use `.filter()` to filter the given arr of keys to the expected arr of picked keys. -Use `.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair. +Use `.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. ```js -const pick = (obj, arr) => - Object - .keys(obj) - .filter((v, i) => arr.indexOf(v) !== -1 ) - .reduce((acc, cur, i) => { - acc[cur] = obj[cur]; - return acc; - }, {}); +const pick = (obj, arr) => arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); // const object = { 'a': 1, 'b': '2', 'c': 3 }; // pick(object, ['a', 'c']) -> { 'a': 1, 'c': 3 } From 383d7a57e4cfd712ff0a640aa77f7a189e55fcbd Mon Sep 17 00:00:00 2001 From: King Date: Wed, 13 Dec 2017 17:51:28 -0500 Subject: [PATCH 12/46] ran| npm run build-list --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index b77013e78..b5aef54c6 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ * [Median of array of numbers](#median-of-array-of-numbers) * [Object from key value pairs](#object-from-key-value-pairs) * [Percentile](#percentile) +* [Pick](#pick) * [Pipe](#pipe) * [Powerset](#powerset) * [Promisify](#promisify) @@ -455,6 +456,20 @@ const percentile = (arr, val) => // percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 ``` +### Pick + +Use `.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. + +```js +const pick = (obj, arr) => arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); + +// const object = { 'a': 1, 'b': '2', 'c': 3 }; +// pick(object, ['a', 'c']) -> { 'a': 1, 'c': 3 } + +// pick(object, ['a', 'c'])['a'] -> 1 +// pick(object, ['a', 'c'])['c'] -> 3 + +``` ### Pipe Use `Array.reduce()` to pass value through functions. From a0106a3c995a8c4189e71e33c25b4c82748e5910 Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Thu, 14 Dec 2017 00:00:04 +0100 Subject: [PATCH 13/46] Refactor palindrome --- README.md | 6 ++++-- snippets/check-for-palindrome.md | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b77013e78..ae83066d1 100644 --- a/README.md +++ b/README.md @@ -146,8 +146,10 @@ Convert string `toLowerCase()` and use `replace()` to remove non-alphanumeric ch Then, `split('')` into individual characters, `reverse()`, `join('')` and compare to the original, unreversed string, after converting it `tolowerCase()`. ```js -const palindrome = str => - str.toLowerCase().replace(/[\W_]/g,'').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g,''); +const palindrome = str => { + const s = str.toLowerCase().replace(/[\W_]/g,''); + return s === s.split('').reverse().join(''); +} // palindrome('taco cat') -> true ``` diff --git a/snippets/check-for-palindrome.md b/snippets/check-for-palindrome.md index bd0452cf8..a22007688 100644 --- a/snippets/check-for-palindrome.md +++ b/snippets/check-for-palindrome.md @@ -4,7 +4,9 @@ Convert string `toLowerCase()` and use `replace()` to remove non-alphanumeric ch Then, `split('')` into individual characters, `reverse()`, `join('')` and compare to the original, unreversed string, after converting it `tolowerCase()`. ```js -const palindrome = str => - str.toLowerCase().replace(/[\W_]/g,'').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g,''); +const palindrome = str => { + const s = str.toLowerCase().replace(/[\W_]/g,''); + return s === s.split('').reverse().join(''); +} // palindrome('taco cat') -> true ``` From 50f302a66c896d9393c7d9544c7eaa2e6a7d3179 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 01:17:10 +0200 Subject: [PATCH 14/46] Styleguide --- .gitignore | 2 + CONTRIBUTING.md | 79 ++++++++++-- currentSnippet.js | 3 - semi-snippets.js | 242 ----------------------------------- snippet-template.md | 4 +- snippets.js | 302 -------------------------------------------- 6 files changed, 74 insertions(+), 558 deletions(-) delete mode 100644 currentSnippet.js delete mode 100644 semi-snippets.js delete mode 100644 snippets.js diff --git a/.gitignore b/.gitignore index c2658d7d1..bc23f6a88 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ node_modules/ + +currentSnippet\.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7e90497d5..09e28829b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,74 @@ ## Contributing -You can contribute to **30 seconds of code** by sending pull requests for snippets that you find useful, reporting issues with current snippets or suggesting changes and/or additions. +**30 seconds of code** is a community effort, so feel free to contribute in any way you can. Every contribution helps! -### Guidelines for new snippets +Here's what you can do to help: -- Snippets must be short. Usually anything above 10 lines would be considered too long, but you can still submit it as it might be possible to shorten it or it might still prove useful regardless of its length. -- Snippets must be explained to a certain extent in the description above them. Make sure to include what functions you are using and why. -- Snippets must solve real-world problems and should be abstract enough to use in different scenarios. This is highly subjective, so send them in anyways. -- Snippets *should* be written in ES6 if possible. -- Snippet files must follow the anchor name conventions of [GitHub Flavored Markdown](https://github.github.com/gfm/), so that the `builder.js` can build the links for the list. -- Use the [template](snippet-template.md) to format your snippets. -- If possible, provide test cases in your Pull Request (link or comment), so that it's easier to verify that each snippet is working. +- [Open issues](https://github.com/Chalarangelo/30-seconds-of-code/issues/new) for things you want to see added or modified. +- Be part of the discussion by helping out with [existing issues](https://github.com/Chalarangelo/30-seconds-of-code/issues) or talking on our [gitter channel](https://gitter.im/30-seconds-of-code/Lobby). +- Submit [pull requests](https://github.com/Chalarangelo/30-seconds-of-code/pulls) with snippets you have created (see below for guidelines). +- Fix typos in existing snippets or run `npm run lint "snippet-name.md"` on unlinted snippets (yes, this is something we actually want help with). + +### Snippet submission and Pull request guidelines + +- **DO NOT MODIFY THE README.md FILE!** Make changes to individual snippet files. You can optionally run `npm run build-list` to update the README.md file automatically, based on the changes you have made. +- **Snippet filenames** must correspond to the title of the snippet. For example if your snippet is titled `### Awesome snippet` the filename should be `awesome-snippet.md`. + - Use `kebab-case`, not `snake_case`. + - Avoid capitalization of words, except if the whole word is capitalized (e.g `URL` should be capitalized in the filename and the snippet title). + - If there are parentheses in the title, add them to the filename (e.g. `awesome-snippet-(extra-awesome).md` if your snippet's title is `Awesome snippet (extra awesome)`). +- **Snippet titles** should have only the first letter of the first word capitalized. Certain words can be in capitals (e.g. `URL`, `RGB`), but this is on a per-snippet basis. + - All snippet titles must be prefixed with `###` and be at the very first line of your snippet. + - Snippet titles must be unique (although if you cannot find a better title, just add some placeholder at the end of the filename and title and we will figure it out). + - Follow snippet titles with an empty line. +- **Snippet descriptions** must be short and to the point. Try to explain *how* the snippet works and what Javascript features are used. Remember to include what functions you are using and why. + - Follow snippet descriptions with an empty line. +- **Snippet code** must be enclosed inside ` ```js ` and ` ``` `. + - Remember to start your snippet's code on a new line below the opening backticks. + - Use ES6 notation to define your function. For example `const myFunction = arg1, arg2 => { }`. + - Try to keep your snippets' code short and to the point. Use modern techniques and features. Make sure to test your code before submitting. + - All snippets must be followed by one (more if necessary) test case after the code, on a new line, in the form of a comment, along with the expected output. The syntax for this is `myFunction('testInput') -> 'testOutput'`. Use multiline comments only if necessary. + - Try to make your function name unique, so that it does not conflict with existing snippets. +- Snippets should be short (usually below 10 lines). If your snippet is longer than that, you can still submit it and we can help you shorten it or figure out ways to improve it. +- Snippets *should* solve real-world problems, no matter how simple. +- Snippets *should* be abstract enough to be applied to different scenarios. +- It is not mandatory, but highly appreciated if you provide **test cases** and/or performance tests (we recommend using [jsPerf](https://jsperf.com/)). +- You can start creating a new snippet, by using the [snippet template](snippet-template.md) to format your snippets. + +### Additional guidelines and conventions regarding snippets + +- When describing snippets, refer to methods, using their full name. For example, use `Array.reduce()`, instead of `reduce()`. +- If your snippet contains argument with default parameters, explain what happens if they are ommited when calling the function and what the default case is. +- If your snippet uses recursion, explain the base cases. +- Always use `const functionName` for function definitions. +- Use variables only when necessary. Prefer `const` when the values are not altered after assignment, otherwise use `let`. Avoid using `var`. +- Use `camelCase` for function and variable names if they consist of more than one word. +- Try to give meaningful names to variables. For example use `letter`, instead of `lt`. Some exceptions by convention are: + - `arr` for arrays (usually as the snippet function's argument). + - `str` for strings. + - `val` or `v` for value (usually when iterating a list, mapping, sorting etc.). + - `acc` for accumulators in `Array.reduce()`. + - `(a,b)` for the two values compared when using `Array.sort()`. + - `i` for indexes. + - `func` for function arguments. + - `nums` for arrays of numbers. +- Use `_` if your function takes no arguments or if an argument inside some function (e.g. `Array.reduce()`) is not used anywhere in your code. +- Specify default parameters for arguments, if necessary. It is preferred to put default parameters last, unless you have pretty good reason not to. +- If your snippet's function takes variadic arguments, use `..args` (although in certain cases, it might be needed to use a different name). +- If your snippet function's body is a single statement, omit the `return` keyword and use an expression instead. +- Always use soft tabs (2 spaces), never hard tabs. +- Omit curly braces (`{` and `}`) whenever possible. +- Always use single quotes for string literals. Use template literals, instead, if necessary. +- If your snippet's code is short enough (around 80 characters), you can make it a single-line function (although not mandatory). Otherwise, use multiple lines. +- Prefer using `Array` methods whenever possible. +- Prefer `Array.concat()` instead of `Array.push()` when working with `Array.reduce()`. +- Use strict equality checking (`===` and `!==` instead of `==` and `!=`), unless you specificly have reason not to. +- Prefer using the ternary operator (`condition ? trueResult : falseResult`) instead of `if else` statements whenever possible. +- Avoid nesting ternary operators (but you can do it if you feel like you should). +- You should define multiple variables on the same line (e.g. `const x = 0, y = 0`) on the same line whenever possible. +- Do not use trailing or leading underscores in variable names. +- Use dot notation (`object.property`) for object properties, when possible. Use bracket notation (`object[variable]`) when accessing object properties using a variable. +- Use arrow functions as much as possible, except when you can't. +- Use semicolons whenever necessary. If your snippet function's body is a single statement, return an expression and add a semicolon at the end. +- Leave a single space after a comma (`,`) character. +- Try to strike a balance between readability, brevity and performance. +- Never use `eval()`. Your snippet will be disqualified immediately. diff --git a/currentSnippet.js b/currentSnippet.js deleted file mode 100644 index 544a140b9..000000000 --- a/currentSnippet.js +++ /dev/null @@ -1,3 +0,0 @@ - -const valueOrDefault = (value, d) => value || d; -// valueOrDefault(NaN, 30) -> 30 diff --git a/semi-snippets.js b/semi-snippets.js deleted file mode 100644 index c35e9d6b8..000000000 --- a/semi-snippets.js +++ /dev/null @@ -1,242 +0,0 @@ - -const anagrams = str => { - if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; - return str.split('').reduce((acc, letter, i) => - acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)), []); -}; -// anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] - -const average = arr => - arr.reduce((acc, val) => acc + val, 0) / arr.length; -// average([1,2,3]) -> 2 - -const bottomVisible = _ => - document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; -// bottomVisible() -> true - -const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); -// capitalizeEveryWord('hello world!') -> 'Hello World!' - -const capitalize = (str, lowerRest = false) => - str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); -// capitalize('myName', true) -> 'Myname' - -const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); }; -/* -chainAsync([ - next => { console.log('0 seconds'); setTimeout(next, 1000); }, - next => { console.log('1 second'); setTimeout(next, 1000); }, - next => { console.log('2 seconds'); } -]) -*/ - -const palindrome = str => - str.toLowerCase().replace(/[\W_]/g, '').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g, ''); -// palindrome('taco cat') -> true - -const chunk = (arr, size) => - Array.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); -// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] - -const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); -// countOccurrences([1,1,2,1,2,3], 1) -> 3 - -const currentUrl = _ => window.location.href; -// currentUrl() -> 'https://google.com' - -const curry = (f, arity = f.length, next) => - (next = prevArgs => - nextArg => { - const args = [ ...prevArgs, nextArg ]; - return args.length >= arity ? f(...args) : next(args); - } - )([]); -// curry(Math.pow)(2)(10) -> 1024 -// curry(Math.min, 3)(10)(50)(2) -> 2 - -const deepFlatten = arr => - arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []); -// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] - -const difference = (arr, values) => arr.filter(v => !values.includes(v)); -// difference([1,2,3], [1,2]) -> [3] - -const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); -// distance(1,1, 2,3) -> 2.23606797749979 - -const isDivisible = (dividend, divisor) => dividend % divisor === 0; -// isDivisible(6,3) -> true - -const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -// escapeRegExp('(test)') -> \\(test\\) - -const isEven = num => Math.abs(num) % 2 === 0; -// isEven(3) -> false - -const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); -// factorial(6) -> 720 - -const fibonacci = n => - Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []); -// fibonacci(5) -> [0,1,1,2,3] - -const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); -// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] - -const flatten = arr => arr.reduce((a, v) => a.concat(v), []); -// flatten([1,[2],3,4]) -> [1,2,3,4] - -const arrayMax = arr => Math.max(...arr); -// arrayMax([10, 1, 5]) -> 10 - -const arrayMin = arr => Math.min(...arr); -// arrayMin([10, 1, 5]) -> 1 - -const getType = v => - v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); -// getType(new Set([1,2,3])) -> "set" - -const getScrollPos = (el = window) => - ({x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, - y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop}); -// getScrollPos() -> {x: 0, y: 200} - -const gcd = (x, y) => !y ? x : gcd(y, x % y); -// gcd (8, 36) -> 4 - -const hammingDistance = (num1, num2) => - ((num1 ^ num2).toString(2).match(/1/g) || '').length; -// hammingDistance(2,3) -> 1 - -const head = arr => arr[0]; -// head([1,2,3]) -> 1 - -const initial = arr => arr.slice(0, -1); -// initial([1,2,3]) -> [1,2] - -const initializeArrayRange = (end, start = 0) => - Array.apply(null, Array(end - start)).map((v, i) => i + start); -// initializeArrayRange(5) -> [0,1,2,3,4] - -const initializeArray = (n, value = 0) => Array(n).fill(value); -// initializeArray(5, 2) -> [2,2,2,2,2] - -const last = arr => arr.slice(-1)[0]; -// last([1,2,3]) -> 3 - -const timeTaken = callback => { - const t0 = performance.now(), r = callback(); - console.log(performance.now() - t0); - return r; -}; -// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) - -const median = arr => { - const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); - return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; -}; -// median([5,6,50,1,-5]) -> 5 -// median([0,10,-2,7]) -> 3.5 - -const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); -// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} - -const percentile = (arr, val) => - 100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; -// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 - -const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg); -// pipe(btoa, x => x.toUpperCase())("Test") -> "VGVZDA==" - -const powerset = arr => - arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); -// powerset([1,2]) -> [[], [1], [2], [2,1]] - -const promisify = func => - (...args) => - new Promise((resolve, reject) => - func(...args, (err, result) => - err ? reject(err) : resolve(result)) - ); -// const delay = promisify((d, cb) => setTimeout(cb, d)) -// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s - -const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; -// randomIntegerInRange(0, 5) -> 2 - -const randomInRange = (min, max) => Math.random() * (max - min) + min; -// randomInRange(2,10) -> 6.0211363285087005 - -const randomizeOrder = arr => arr.sort((a, b) => Math.random() >= 0.5 ? -1 : 1); -// randomizeOrder([1,2,3]) -> [1,3,2] - -const redirect = (url, asLink = true) => - asLink ? window.location.href = url : window.location.replace(url); -// redirect('https://google.com') - -const reverseString = str => [...str].reverse().join(''); -// reverseString('foobar') -> 'raboof' - -const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); -// rgbToHex(255, 165, 1) -> 'ffa501' - -const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); -// const delay = (d) => new Promise(r => setTimeout(r, d)) -// series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete - -const scrollToTop = _ => { - const c = document.documentElement.scrollTop || document.body.scrollTop; - if (c > 0) { - window.requestAnimationFrame(scrollToTop); - window.scrollTo(0, c - c / 8); - } -}; -// scrollToTop() - -const shuffle = arr => { - let r = arr.map(Math.random); - return arr.sort((a, b) => r[a] - r[b]); -}; -// shuffle([1,2,3]) -> [2, 1, 3] - -const similarity = (arr, values) => arr.filter(v => values.includes(v)); -// similarity([1,2,3], [1,2,4]) -> [1,2] - -const sortCharactersInString = str => - str.split('').sort((a, b) => a.localeCompare(b)).join(''); -// sortCharactersInString('cabbage') -> 'aabbceg' - -const sum = arr => arr.reduce((acc, val) => acc + val, 0); -// sum([1,2,3,4]) -> 10 - -[varA, varB] = [varB, varA]; -// [x, y] = [y, x] - -const tail = arr => arr.length > 1 ? arr.slice(1) : arr; -// tail([1,2,3]) -> [2,3] -// tail([1]) -> [1] - -const truncate = (str, num) => - str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; -// truncate('boomerang', 7) -> 'boom...' - -const unique = arr => [...new Set(arr)]; -// unique([1,2,2,3,4,4,5]) -> [1,2,3,4,5] - -const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))?/g).reduce( - (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} - ); -// getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} - -const uuid = _ => - ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => - (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) - ); -// uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' - -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); -// validateNumber('10') -> true - -const valueOrDefault = (value, d) => value || d; -// valueOrDefault(NaN, 30) -> 30 diff --git a/snippet-template.md b/snippet-template.md index e258fe079..83e820965 100644 --- a/snippet-template.md +++ b/snippet-template.md @@ -1,9 +1,9 @@ ### Snippet title -Explain briefly how the snippet works +Explain briefly how the snippet works. ```js -const functionName = arguments => +const functionName = arguments => {functionBody} // functionName(sampleInput) -> sampleOutput ``` diff --git a/snippets.js b/snippets.js deleted file mode 100644 index d754bf389..000000000 --- a/snippets.js +++ /dev/null @@ -1,302 +0,0 @@ - -const anagrams = str => { - if(str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str]; - return str.split('').reduce( (acc, letter, i) => - acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => letter + val )), []); -} -// anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] - - -const average = arr => - arr.reduce( (acc , val) => acc + val, 0) / arr.length; -// average([1,2,3]) -> 2 - - -const bottomVisible = _ => - document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; -// bottomVisible() -> true - - -const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); -// capitalizeEveryWord('hello world!') -> 'Hello World!' - - -const capitalize = (str, lowerRest = false) => - str.slice(0, 1).toUpperCase() + (lowerRest? str.slice(1).toLowerCase() : str.slice(1)); -// capitalize('myName', true) -> 'Myname' - - -const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); } -/* -chainAsync([ - next => { console.log('0 seconds'); setTimeout(next, 1000); }, - next => { console.log('1 second'); setTimeout(next, 1000); }, - next => { console.log('2 seconds'); } -]) -*/ - - -const palindrome = str => - str.toLowerCase().replace(/[\W_]/g,'').split('').reverse().join('') === str.toLowerCase().replace(/[\W_]/g,''); -// palindrome('taco cat') -> true - - -const chunk = (arr, size) => - Array.apply(null, {length: Math.ceil(arr.length/size)}).map((v, i) => arr.slice(i*size, i*size+size)); -// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] - - -const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); -// countOccurrences([1,1,2,1,2,3], 1) -> 3 - - -const currentUrl = _ => window.location.href; -// currentUrl() -> 'https://google.com' - - -const curry = (f, arity = f.length, next) => - (next = prevArgs => - nextArg => { - const args = [ ...prevArgs, nextArg ]; - return args.length >= arity ? f(...args) : next(args); - } - )([]); -// curry(Math.pow)(2)(10) -> 1024 -// curry(Math.min, 3)(10)(50)(2) -> 2 - - -const deepFlatten = arr => - arr.reduce( (a, v) => a.concat( Array.isArray(v) ? deepFlatten(v) : v ), []); -// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] - - -const difference = (arr, values) => arr.filter(v => !values.includes(v)); -// difference([1,2,3], [1,2]) -> [3] - - -const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); -// distance(1,1, 2,3) -> 2.23606797749979 - - -const isDivisible = (dividend, divisor) => dividend % divisor === 0; -// isDivisible(6,3) -> true - - -const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -// escapeRegExp('(test)') -> \\(test\\) - - -const isEven = num => Math.abs(num) % 2 === 0; -// isEven(3) -> false - - -const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); -// factorial(6) -> 720 - - -const fibonacci = n => - Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),[]); -// fibonacci(5) -> [0,1,1,2,3] - - -const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); -// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] - - -const flatten = arr => arr.reduce( (a, v) => a.concat(v), []); -// flatten([1,[2],3,4]) -> [1,2,3,4] - - -const arrayMax = arr => Math.max(...arr); -// arrayMax([10, 1, 5]) -> 10 - - -const arrayMin = arr => Math.min(...arr); -// arrayMin([10, 1, 5]) -> 1 - - -const getType = v => - v === undefined ? "undefined" : v === null ? "null" : v.constructor.name.toLowerCase(); -// getType(new Set([1,2,3])) -> "set" - - -const getScrollPos = (el = window) => - ( {x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft, - y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop} ); -// getScrollPos() -> {x: 0, y: 200} - - -const gcd = (x , y) => !y ? x : gcd(y, x % y); -// gcd (8, 36) -> 4 - - -const hammingDistance = (num1, num2) => - ((num1^num2).toString(2).match(/1/g) || '').length; -// hammingDistance(2,3) -> 1 - - -const head = arr => arr[0]; -// head([1,2,3]) -> 1 - - -const initial = arr => arr.slice(0,-1); -// initial([1,2,3]) -> [1,2] - - -const initializeArrayRange = (end, start = 0) => - Array.apply(null, Array(end-start)).map( (v,i) => i + start ); -// initializeArrayRange(5) -> [0,1,2,3,4] - - -const initializeArray = (n, value = 0) => Array(n).fill(value); -// initializeArray(5, 2) -> [2,2,2,2,2] - - -const last = arr => arr.slice(-1)[0]; -// last([1,2,3]) -> 3 - - -const timeTaken = callback => { - const t0 = performance.now(), r = callback(); - console.log(performance.now() - t0); - return r; -} -// timeTaken(() => Math.pow(2, 10)) -> 1024 (0.010000000009313226 logged in console) - - -const median = arr => { - const mid = Math.floor(arr.length / 2), nums = arr.sort((a,b) => a - b); - return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; -} -// median([5,6,50,1,-5]) -> 5 -// median([0,10,-2,7]) -> 3.5 - - -const objectFromPairs = arr => arr.reduce((a,v) => (a[v[0]] = v[1], a), {}); -// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2} - - -const percentile = (arr, val) => - 100 * arr.reduce((acc,v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length; -// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55 - - -const pipe = (...funcs) => arg => funcs.reduce((acc, func) => func(acc), arg); -// pipe(btoa, x => x.toUpperCase())("Test") -> "VGVZDA==" - - -const powerset = arr => - arr.reduce( (a,v) => a.concat(a.map( r => [v].concat(r) )), [[]]); -// powerset([1,2]) -> [[], [1], [2], [2,1]] - - -const promisify = func => - (...args) => - new Promise((resolve, reject) => - func(...args, (err, result) => - err ? reject(err) : resolve(result)) - ); -// const delay = promisify((d, cb) => setTimeout(cb, d)) -// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s - - -const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; -// randomIntegerInRange(0, 5) -> 2 - - -const randomInRange = (min, max) => Math.random() * (max - min) + min; -// randomInRange(2,10) -> 6.0211363285087005 - - -const randomizeOrder = arr => arr.sort( (a,b) => Math.random() >= 0.5 ? -1 : 1); -// randomizeOrder([1,2,3]) -> [1,3,2] - - -const redirect = (url, asLink = true) => - asLink ? window.location.href = url : window.location.replace(url); -// redirect('https://google.com') - - -const reverseString = str => [...str].reverse().join(''); -// reverseString('foobar') -> 'raboof' - - -const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); -// rgbToHex(255, 165, 1) -> 'ffa501' - - -const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()); -// const delay = (d) => new Promise(r => setTimeout(r, d)) -// series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete - - -const scrollToTop = _ => { - const c = document.documentElement.scrollTop || document.body.scrollTop; - if(c > 0) { - window.requestAnimationFrame(scrollToTop); - window.scrollTo(0, c - c/8); - } -} -// scrollToTop() - - -const shuffle = arr => { - let r = arr.map(Math.random); - return arr.sort((a,b) => r[a] - r[b]); -} -// shuffle([1,2,3]) -> [2, 1, 3] - - -const similarity = (arr, values) => arr.filter(v => values.includes(v)); -// similarity([1,2,3], [1,2,4]) -> [1,2] - - -const sortCharactersInString = str => - str.split('').sort( (a,b) => a.localeCompare(b) ).join(''); -// sortCharactersInString('cabbage') -> 'aabbceg' - - -const sum = arr => arr.reduce( (acc , val) => acc + val, 0); -// sum([1,2,3,4]) -> 10 - - -[varA, varB] = [varB, varA]; -// [x, y] = [y, x] - - -const tail = arr => arr.length > 1 ? arr.slice(1) : arr; -// tail([1,2,3]) -> [2,3] -// tail([1]) -> [1] - - -const truncate = (str, num) => - str.length > num ? str.slice(0, num > 3 ? num-3 : num) + '...' : str; -// truncate('boomerang', 7) -> 'boom...' - - -const unique = arr => [...new Set(arr)]; -// unique([1,2,2,3,4,4,5]) -> [1,2,3,4,5] - - -const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))?/g).reduce( - (a,v) => (a[v.slice(0,v.indexOf('='))] = v.slice(v.indexOf('=')+1), a), {} - ); -// getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} - - -const uuid = _ => - ( [1e7]+-1e3+-4e3+-8e3+-1e11 ).replace( /[018]/g, c => - (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) - ); -// uuid() -> '7982fcfe-5721-4632-bede-6000885be57d' - - -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); -// validateNumber('10') -> true - - -const valueOrDefault = (value, d) => value || d; -// valueOrDefault(NaN, 30) -> 30 - - From e7252bb7deeb79bfec2d5ef853f30d361dd9a2d4 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 01:34:24 +0200 Subject: [PATCH 15/46] Lint pick, build README --- README.md | 13 +++++-------- snippets/pick.md | 14 +++++--------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 332fba4bc..21d6bafb2 100644 --- a/README.md +++ b/README.md @@ -457,18 +457,15 @@ const percentile = (arr, val) => ### Pick -Use `.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. +Use `Array.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. ```js -const pick = (obj, arr) => arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); - -// const object = { 'a': 1, 'b': '2', 'c': 3 }; -// pick(object, ['a', 'c']) -> { 'a': 1, 'c': 3 } - +const pick = (obj, arr) => + arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); +// pick({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c']) -> { 'a': 1, 'c': 3 } // pick(object, ['a', 'c'])['a'] -> 1 -// pick(object, ['a', 'c'])['c'] -> 3 - ``` + ### Pipe Use `Array.reduce()` to pass value through functions. diff --git a/snippets/pick.md b/snippets/pick.md index c3b5cd2f2..3689e4a28 100644 --- a/snippets/pick.md +++ b/snippets/pick.md @@ -1,14 +1,10 @@ ### Pick -Use `.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. +Use `Array.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj. ```js -const pick = (obj, arr) => arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); - -// const object = { 'a': 1, 'b': '2', 'c': 3 }; -// pick(object, ['a', 'c']) -> { 'a': 1, 'c': 3 } - +const pick = (obj, arr) => + arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}); +// pick({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c']) -> { 'a': 1, 'c': 3 } // pick(object, ['a', 'c'])['a'] -> 1 -// pick(object, ['a', 'c'])['c'] -> 3 - -``` \ No newline at end of file +``` From 24468a0afff3dfcca197bf299f5331d8bbec52d8 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 01:46:30 +0200 Subject: [PATCH 16/46] Object to key-value pairs description, linting, build README --- README.md | 2 ++ snippets/object-to-key-value-pairs.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 2cd816916..b449e0318 100644 --- a/README.md +++ b/README.md @@ -447,6 +447,8 @@ const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); ### Object to key-value pairs +Use `Object.keys()` and `Array.map()` to iterate over the object's keys and produce an array with key-value pairs. + ```js const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); // objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) diff --git a/snippets/object-to-key-value-pairs.md b/snippets/object-to-key-value-pairs.md index 78fd63811..fb639e432 100644 --- a/snippets/object-to-key-value-pairs.md +++ b/snippets/object-to-key-value-pairs.md @@ -1,5 +1,7 @@ ### Object to key-value pairs +Use `Object.keys()` and `Array.map()` to iterate over the object's keys and produce an array with key-value pairs. + ```js const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); // objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) From 2b34ee4ba92f13c0b0d4f653e8e2fde7f1ca2601 Mon Sep 17 00:00:00 2001 From: Darren Scerri Date: Thu, 14 Dec 2017 01:11:38 +0100 Subject: [PATCH 17/46] Fix names and links --- README.md | 6 +++--- snippets/array-difference.md | 2 +- snippets/array-intersection.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ddd428064..7ccd59b50 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -89,7 +89,7 @@ const anagrams = str => { // anagrams('abc') -> ['abc','acb','bac','bca','cab','cba'] ``` -### Array difference (complement) +### Array difference Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. @@ -98,7 +98,7 @@ const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has // difference([1,2,3], [1,2]) -> [3] ``` -### Array intersection (Common values between two arrays) +### Array intersection Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. diff --git a/snippets/array-difference.md b/snippets/array-difference.md index 74e518f5c..46469b1d6 100644 --- a/snippets/array-difference.md +++ b/snippets/array-difference.md @@ -1,4 +1,4 @@ -### Array difference (complement) +### Array difference Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values not contained in `b`. diff --git a/snippets/array-intersection.md b/snippets/array-intersection.md index 909c4312d..87c42378b 100644 --- a/snippets/array-intersection.md +++ b/snippets/array-intersection.md @@ -1,4 +1,4 @@ -### Array intersection (Common values between two arrays) +### Array intersection Create a `Set` from `b`, then use `Array.filter()` on `a` to only keep values contained in `b`. From 38596dcaa53e54ff087c802b847c62b54f671b5b Mon Sep 17 00:00:00 2001 From: Michael Goldspinner Date: Wed, 13 Dec 2017 23:53:34 -0500 Subject: [PATCH 18/46] Ordinal Suffix hotfix mismatched variables. --- snippets/get-ordinal-suffix-of-number.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/get-ordinal-suffix-of-number.md b/snippets/get-ordinal-suffix-of-number.md index cda41b9ac..725ff05b4 100644 --- a/snippets/get-ordinal-suffix-of-number.md +++ b/snippets/get-ordinal-suffix-of-number.md @@ -12,7 +12,7 @@ const toOrdinalSuffix = int => { var oPattern = [1,2,3,4]; var tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] - return pattern.includes(digits[0]) && !teens.includes(digits[1]) ? int + suffix[digits[0]-1] : int + suffix[3]; + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; } // toOrdinalSuffix("123") -> "123rd" ``` \ No newline at end of file From 5fbfa9422c7fc29ac20e0a6b58bfc4f2e63d440f Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Wed, 13 Dec 2017 21:20:36 -0800 Subject: [PATCH 19/46] Update README.md Remove the Question mark as per https://github.com/Chalarangelo/30-seconds-of-code/issues/95 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ddd428064..3dc91bb5e 100644 --- a/README.md +++ b/README.md @@ -705,7 +705,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + url.match(/([^?=&]+)(=([^&]*))/g).reduce( (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} From e421b1d49d92c1a95a30fe6fa7b157ea4a3426dd Mon Sep 17 00:00:00 2001 From: panshao <1016432619@qq.com> Date: Thu, 14 Dec 2017 14:09:46 +0800 Subject: [PATCH 20/46] Update README.md use Array.from instead of Array.apply --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ddd428064..46f4ff8e9 100644 --- a/README.md +++ b/README.md @@ -185,14 +185,14 @@ const palindrome = str => { ### Chunk array -Use `Array.apply()` to create a new array, that fits the number of chunks that will be produced. -Use `Array.map()` to map each element of the new array to a chunk the length of `size`. +Use `Array.from(arrayLike[, mapFn[, thisArg]])` to create a new array, that fits the number of chunks that will be produced. +Use `mapFn` to map each element of the new array to a chunk the length of `size`. If the original array can't be split evenly, the final chunk will contain the remaining elements. ```js const chunk = (arr, size) => - Array.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); -// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] + Array.from({length: Math.ceil(arr.length / size)}, (v, i) => arr.slice(i * size, i * size + size)); + // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` ### Count occurrences of a value in array From 5f7add56646d421d977af162498a81a1c8559e4f Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 01:19:15 -0500 Subject: [PATCH 21/46] add compact.md & ran npm run build-list --- README.md | 11 ++++++++++- snippets/compact.md | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 snippets/compact.md diff --git a/README.md b/README.md index ddd428064..3d2cc38a8 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ * [Chain asynchronous functions](#chain-asynchronous-functions) * [Check for palindrome](#check-for-palindrome) * [Chunk array](#chunk-array) +* [Compact](#compact) * [Count occurrences of a value in array](#count-occurrences-of-a-value-in-array) * [Current URL](#current-url) * [Curry](#curry) @@ -55,7 +56,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -195,6 +196,14 @@ const chunk = (arr, size) => // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` +### Compact + +Use `.filter()` to filter falsey values. For example false, null, 0, "", undefined, and NaN are falsey. + +```js +const compact = (arr) => arr.filter( v => [0, null, false, '', undefined].indexOf(v) === -1 && v); +// compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] +``` ### Count occurrences of a value in array Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. diff --git a/snippets/compact.md b/snippets/compact.md new file mode 100644 index 000000000..de76f834b --- /dev/null +++ b/snippets/compact.md @@ -0,0 +1,8 @@ +### Compact + +Use `.filter()` to filter falsey values. For example false, null, 0, "", undefined, and NaN are falsey. + +```js +const compact = (arr) => arr.filter( v => [0, null, false, '', undefined].indexOf(v) === -1 && v); +// compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] +``` \ No newline at end of file From b6f19c47c20d917bbc03c06ebc1041ccd051eac3 Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Wed, 13 Dec 2017 23:53:53 -0800 Subject: [PATCH 22/46] Fix: validateNumber: check cooercian now passes all 16 test cases --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ddd428064..261ff99a6 100644 --- a/README.md +++ b/README.md @@ -729,7 +729,7 @@ Use `!isNaN` in combination with `parseFloat()` to check if the argument is a nu Use `isFinite()` to check if the number is finite. ```js -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; // validateNumber('10') -> true ``` From e8347a46782b68734138d79917ab6793b22ca91e Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 02:56:47 -0500 Subject: [PATCH 23/46] 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 0c5f677688a5ea8ae598e27ea7b879ccb6db0d0a Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 03:00:29 -0500 Subject: [PATCH 24/46] ran npm run build-list --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d2cc38a8..31007af89 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ const chunk = (arr, size) => Use `.filter()` to filter falsey values. For example false, null, 0, "", undefined, and NaN are falsey. ```js -const compact = (arr) => arr.filter( v => [0, null, false, '', undefined].indexOf(v) === -1 && v); +const compact = (arr) => arr.filter(v => v); // compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] ``` ### Count occurrences of a value in array From 2903ece39bbe619e347a2d26ab3d54827bc4dcea Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:06:13 +0200 Subject: [PATCH 25/46] Update compact.md Updated description a little. --- snippets/compact.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/snippets/compact.md b/snippets/compact.md index 92dd9b767..607634b4a 100644 --- a/snippets/compact.md +++ b/snippets/compact.md @@ -1,8 +1,8 @@ ### Compact -Use `.filter()` to filter falsey values. For example false, null, 0, "", undefined, and NaN are falsey. +Use `Array.filter()` to filter out falsey values (`false`, `null`, `0`, `""`, `undefined`, and `NaN`). ```js const compact = (arr) => arr.filter(v => v); // compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] -``` \ No newline at end of file +``` From 5fe1485d64ae245b0741e2f434891d97aac75252 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:07:14 +0200 Subject: [PATCH 26/46] Build README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 31007af89..b23877de1 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -198,12 +198,13 @@ const chunk = (arr, size) => ### Compact -Use `.filter()` to filter falsey values. For example false, null, 0, "", undefined, and NaN are falsey. +Use `Array.filter()` to filter out falsey values (`false`, `null`, `0`, `""`, `undefined`, and `NaN`). ```js const compact = (arr) => arr.filter(v => v); // compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] ``` + ### Count occurrences of a value in array Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. From d563b73b7d6d9bea5fd9d51b46db59c7f83e364f Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Wed, 13 Dec 2017 23:53:53 -0800 Subject: [PATCH 27/46] Revert "Fix: validateNumber: check cooercian" This reverts commit d66511410af1bbb9c479791606ed631ca4dd203a. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 261ff99a6..ddd428064 100644 --- a/README.md +++ b/README.md @@ -729,7 +729,7 @@ Use `!isNaN` in combination with `parseFloat()` to check if the argument is a nu Use `isFinite()` to check if the number is finite. ```js -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); // validateNumber('10') -> true ``` From 960fa239bcb1d91976643d899abcd4b424866b7d Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:15:43 +0200 Subject: [PATCH 28/46] Update get-ordinal-suffix-of-number.md --- snippets/get-ordinal-suffix-of-number.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/snippets/get-ordinal-suffix-of-number.md b/snippets/get-ordinal-suffix-of-number.md index 725ff05b4..f8832638b 100644 --- a/snippets/get-ordinal-suffix-of-number.md +++ b/snippets/get-ordinal-suffix-of-number.md @@ -5,14 +5,11 @@ Find which ordinal pattern digits match. If digit is found in teens pattern, use teens ordinal. ```js -const toOrdinalSuffix = int => { - int = parseInt(int); - var digits = [ (int % 10), (int % 100)]; - var ordinals = ["st", "nd", "rd", "th"]; - var oPattern = [1,2,3,4]; - var tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] - - return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; +const toOrdinalSuffix = num => { + const int = parseInt(num), digits = [(int % 10), (int % 100)], + ordinals = ["st", "nd", "rd", "th"], oPattern = [1,2,3,4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; } // toOrdinalSuffix("123") -> "123rd" -``` \ No newline at end of file +``` From 465935215f588df85aeeba935a4223c887b05aa9 Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Thu, 14 Dec 2017 00:15:57 -0800 Subject: [PATCH 29/46] Fix: do the change in the individual .md file --- snippets/validate-number.md | 1 + 1 file changed, 1 insertion(+) diff --git a/snippets/validate-number.md b/snippets/validate-number.md index a26eca627..2e2b3f970 100644 --- a/snippets/validate-number.md +++ b/snippets/validate-number.md @@ -2,6 +2,7 @@ Use `!isNaN` in combination with `parseFloat()` to check if the argument is a number. Use `isFinite()` to check if the number is finite. +Use `Number()` to check if the coercion holds. ```js const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); From f37272cd01f7b8ddb8e7354167dfc685bf551bd3 Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Thu, 14 Dec 2017 00:17:19 -0800 Subject: [PATCH 30/46] Fix: actually update the code snippet, not just the blurb --- snippets/validate-number.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/validate-number.md b/snippets/validate-number.md index 2e2b3f970..60a037e3e 100644 --- a/snippets/validate-number.md +++ b/snippets/validate-number.md @@ -5,6 +5,6 @@ Use `isFinite()` to check if the number is finite. Use `Number()` to check if the coercion holds. ```js -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; // validateNumber('10') -> true ``` From aac891ad96adcf51ed4f1c0c64f17aced67402d3 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:17:37 +0200 Subject: [PATCH 31/46] Build README --- README.md | 17 +++++++++++++++++ ...of-number.md => ordinal-suffix-of-number.md} | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) rename snippets/{get-ordinal-suffix-of-number.md => ordinal-suffix-of-number.md} (94%) diff --git a/README.md b/README.md index b23877de1..ee07a577e 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ * [Median of array of numbers](#median-of-array-of-numbers) * [Object from key value pairs](#object-from-key-value-pairs) * [Object to key value pairs](#object-to-key-value-pairs) +* [Ordinal suffix of number](#ordinal-suffix-of-number) * [Percentile](#percentile) * [Pick](#pick) * [Pipe](#pipe) @@ -486,6 +487,22 @@ const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); // objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]]) ``` +### Ordinal suffix of number + +Use the modulo operator (`%`) to find values of single and tens digits. +Find which ordinal pattern digits match. +If digit is found in teens pattern, use teens ordinal. + +```js +const toOrdinalSuffix = num => { + const int = parseInt(num), digits = [(int % 10), (int % 100)], + ordinals = ["st", "nd", "rd", "th"], oPattern = [1,2,3,4], + tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19] + return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0]-1] : int + ordinals[3]; +} +// toOrdinalSuffix("123") -> "123rd" +``` + ### Percentile Use `Array.reduce()` to calculate how many numbers are below the value and how many are the same value and diff --git a/snippets/get-ordinal-suffix-of-number.md b/snippets/ordinal-suffix-of-number.md similarity index 94% rename from snippets/get-ordinal-suffix-of-number.md rename to snippets/ordinal-suffix-of-number.md index f8832638b..4e849eff7 100644 --- a/snippets/get-ordinal-suffix-of-number.md +++ b/snippets/ordinal-suffix-of-number.md @@ -1,4 +1,4 @@ -### Get Ordinal Suffix of Number +### Ordinal suffix of number Use the modulo operator (`%`) to find values of single and tens digits. Find which ordinal pattern digits match. From 9e63ad8975ea01f0d6623a1468e023422d6a9cc8 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:21:18 +0200 Subject: [PATCH 32/46] Build README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ee07a577e..458bf5611 100644 --- a/README.md +++ b/README.md @@ -754,9 +754,10 @@ const uuid = _ => Use `!isNaN` in combination with `parseFloat()` to check if the argument is a number. Use `isFinite()` to check if the number is finite. +Use `Number()` to check if the coercion holds. ```js -const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n); +const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; // validateNumber('10') -> true ``` From 494189089e7c760da4bde2e65c6d5ed8f81793c3 Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Wed, 13 Dec 2017 21:20:36 -0800 Subject: [PATCH 33/46] Revert "Update README.md" This reverts commit 682f172645a7b16f640f966f25b02de0cd12f55b. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3dc91bb5e..ddd428064 100644 --- a/README.md +++ b/README.md @@ -705,7 +705,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))/g).reduce( + url.match(/([^?=&]+)(=([^&]*))?/g).reduce( (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} From e6bfe6606f9ef20468d667cadd7a478bcf80cede Mon Sep 17 00:00:00 2001 From: Robert Mennell Date: Thu, 14 Dec 2017 00:23:14 -0800 Subject: [PATCH 34/46] Fix: remove one or more quantifier from Match to properly pull out parts --- snippets/URL-parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/URL-parameters.md b/snippets/URL-parameters.md index 742e7ffbd..f78c774d8 100644 --- a/snippets/URL-parameters.md +++ b/snippets/URL-parameters.md @@ -5,7 +5,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + url.match(/([^?=&]+)(=([^&]*))/g).reduce( (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} From 3fae1fa34a953bf262f02fc9ed69df7ac34d4553 Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 03:24:05 -0500 Subject: [PATCH 35/46] update description of head & ran npm run build-list --- README.md | 4 ++-- snippets/head-of-list.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 458bf5611..c26a5677d 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -395,7 +395,7 @@ const hammingDistance = (num1, num2) => ### Head of list -Return `arr[0]`. +Use `arr[0]` to return the first element of the passed array. ```js const head = arr => arr[0]; diff --git a/snippets/head-of-list.md b/snippets/head-of-list.md index 31dc5fbaf..c2e0d5a3a 100644 --- a/snippets/head-of-list.md +++ b/snippets/head-of-list.md @@ -1,6 +1,6 @@ ### Head of list -Return `arr[0]`. +Use `arr[0]` to return the first element of the passed array. ```js const head = arr => arr[0]; From 3ce9c180c59c35a0446c1296cf9072ebf93e5b60 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:26:08 +0200 Subject: [PATCH 36/46] Build README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a125ed5c6..850d944cf 100644 --- a/README.md +++ b/README.md @@ -732,7 +732,7 @@ Pass `location.search` as the argument to apply to the current `url`. ```js const getUrlParameters = url => - url.match(/([^?=&]+)(=([^&]*))?/g).reduce( + url.match(/([^?=&]+)(=([^&]*))/g).reduce( (a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {} ); // getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'} From 80af3e7c6d06b9baa743b477226b675b4391880e Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:28:09 +0200 Subject: [PATCH 37/46] Build README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af1cd5ccb..4dbfe200a 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) From e98fd5fe3ab0aa76168d5898ca51d813c5f67df5 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:32:59 +0200 Subject: [PATCH 38/46] 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 9980dbac0f596e99e08853057e88a4d49f0caa1d Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:34:29 +0200 Subject: [PATCH 39/46] Update sleep.md --- snippets/sleep.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/sleep.md b/snippets/sleep.md index 4a7e8916b..c64ed3917 100644 --- a/snippets/sleep.md +++ b/snippets/sleep.md @@ -1,6 +1,6 @@ ### Sleep -If you have an async function and you want to delay executing part of it. you can put your async function to sleep(in miliseconds). +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)); From 27c02041fd0ed0afc685d5d771cd31d440689afa Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:35:58 +0200 Subject: [PATCH 40/46] Build README --- README.md | 16 ++++++++++++++++ snippets/sleep.md | 12 +++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 88d89840c..8b9c31e13 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ * [Scroll to top](#scroll-to-top) * [Shuffle array values](#shuffle-array-values) * [Similarity between arrays](#similarity-between-arrays) +* [Sleep](#sleep) * [Sort characters in string (alphabetical)](#sort-characters-in-string-alphabetical) * [Sum of array of numbers](#sum-of-array-of-numbers) * [Swap values of two variables](#swap-values-of-two-variables) @@ -667,6 +668,21 @@ const similarity = (arr, values) => arr.filter(v => values.includes(v)); // similarity([1,2,3], [1,2,4]) -> [1,2] ``` +### Sleep + +Delay executing part of an `async` function, by putting it to sleep, returning a `Promise`. + +```js +const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); +/* +async function sleepyWork() { + console.log('I\'m going to sleep for 1 second.'); + await sleep(1000); + console.log('I woke up after 1 second.'); +} +*/ +``` + ### Sort characters in string (alphabetical) Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, recombine using `join('')`. diff --git a/snippets/sleep.md b/snippets/sleep.md index c64ed3917..e2a58d0bd 100644 --- a/snippets/sleep.md +++ b/snippets/sleep.md @@ -4,9 +4,11 @@ Delay executing part of an `async` function, by putting it to sleep, returning a ```js const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); -// async function sleepyWork() { -// console.log('I\'m going to sleep for 1 second.'); -// await sleep(1000); -// console.log('I woke up after 1 second.'); -// } +/* +async function sleepyWork() { + console.log('I\'m going to sleep for 1 second.'); + await sleep(1000); + console.log('I woke up after 1 second.'); +} +*/ ``` From 755425f5562215404aef5cd59a9d00eeb16246de Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 03:44:45 -0500 Subject: [PATCH 41/46] ran npm run build-list & update intial-of-list description --- README.md | 4 ++-- snippets/initial-of-list.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8b9c31e13..f370a585a 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -405,7 +405,7 @@ const head = arr => arr[0]; ### Initial of list -Return `arr.slice(0,-1)`. +Use `arr.slice(0,-1)`to return all but the last element of the array. ```js const initial = arr => arr.slice(0, -1); diff --git a/snippets/initial-of-list.md b/snippets/initial-of-list.md index a222f2306..1f967f804 100644 --- a/snippets/initial-of-list.md +++ b/snippets/initial-of-list.md @@ -1,6 +1,6 @@ ### Initial of list -Return `arr.slice(0,-1)`. +Use `arr.slice(0,-1)`to return all but the last element of the array. ```js const initial = arr => arr.slice(0, -1); From 91f393207df999ed0ef1cf715f08426d570bd426 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:45:09 +0200 Subject: [PATCH 42/46] Update group-by Shortened code. It now also follows the styleguide more precisely. Improved description. --- snippets/group-by | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/snippets/group-by b/snippets/group-by index 53383db3a..e6df1a2a7 100644 --- a/snippets/group-by +++ b/snippets/group-by @@ -1,16 +1,14 @@ ### Group by -Passing an array of values, a function or a property name thats going to be run against each value in the array, -returns an object where the keys are the mapped results and the values is an array of the original values that generated the same results. +Use `Array.map()` to map the values of an array to a function or property name. +Use `Array.reduce()` to create an object, where the keys are produced from the mapped results. ```js -const groupBy = (values, fn) => { - return (typeof fn === 'function' ? values.map(fn) : values.map((val) => val[fn])) +const groupBy = (arr, func) => + (typeof func === 'function' ? arr.map(func) : arr.map(val => val[func])) .reduce((acc, val, i) => { - acc[val] = acc[val] === undefined ? [values[i]] : acc[val].concat(values[i]); - return acc; + acc[val] = acc[val] === undefined ? [arr[i]] : acc[val].concat(arr[i]); return acc; }, {}); -} // groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]} // groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} ``` From 2afdce90ee3d55ce14ce9a8d8e0bb7614e1accc3 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:46:46 +0200 Subject: [PATCH 43/46] Build README --- README.md | 16 ++++++++++++++++ snippets/{group-by => group-by.md} | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) rename snippets/{group-by => group-by.md} (94%) diff --git a/README.md b/README.md index 8b9c31e13..522f36584 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ * [Get native type of value](#get-native-type-of-value) * [Get scroll position](#get-scroll-position) * [Greatest common divisor (GCD)](#greatest-common-divisor-gcd) +* [Group by](#group-by) * [Hamming distance](#hamming-distance) * [Head of list](#head-of-list) * [Initial of list](#initial-of-list) @@ -383,6 +384,21 @@ const gcd = (x, y) => !y ? x : gcd(y, x % y); // gcd (8, 36) -> 4 ``` +### Group by + +Use `Array.map()` to map the values of an array to a function or property name. +Use `Array.reduce()` to create an object, where the keys are produced from the mapped results. + +```js +const groupBy = (arr, func) => + (typeof func === 'function' ? arr.map(func) : arr.map(val => val[func])) + .reduce((acc, val, i) => { + acc[val] = acc[val] === undefined ? [arr[i]] : acc[val].concat(arr[i]); return acc; + }, {}); +// groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]} +// groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']} +``` + ### Hamming distance Use XOR operator (`^`) to find the bit difference between the two numbers, convert to binary string using `toString(2)`. diff --git a/snippets/group-by b/snippets/group-by.md similarity index 94% rename from snippets/group-by rename to snippets/group-by.md index e6df1a2a7..ab833c9d2 100644 --- a/snippets/group-by +++ b/snippets/group-by.md @@ -4,7 +4,7 @@ Use `Array.map()` to map the values of an array to a function or property name. Use `Array.reduce()` to create an object, where the keys are produced from the mapped results. ```js -const groupBy = (arr, func) => +const groupBy = (arr, func) => (typeof func === 'function' ? arr.map(func) : arr.map(val => val[func])) .reduce((acc, val, i) => { acc[val] = acc[val] === undefined ? [arr[i]] : acc[val].concat(arr[i]); return acc; From 2123d8d50a72b26003f1d8525426c84265cab871 Mon Sep 17 00:00:00 2001 From: King Date: Thu, 14 Dec 2017 03:49:18 -0500 Subject: [PATCH 44/46] update last-of-list & ran npm run build-list --- README.md | 4 ++-- snippets/last-of-list.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8b9c31e13..d267e205a 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to URL](#redirect-to-url) +* [Redirect to url](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -435,7 +435,7 @@ const initializeArray = (n, value = 0) => Array(n).fill(value); ### Last of list -Return `arr.slice(-1)[0]`. +Use `arr.slice(-1)[0]` to get the last element of the given array. ```js const last = arr => arr.slice(-1)[0]; diff --git a/snippets/last-of-list.md b/snippets/last-of-list.md index 16955f201..d27b0b35e 100644 --- a/snippets/last-of-list.md +++ b/snippets/last-of-list.md @@ -1,6 +1,6 @@ ### Last of list -Return `arr.slice(-1)[0]`. +Use `arr.slice(-1)[0]` to get the last element of the given array. ```js const last = arr => arr.slice(-1)[0]; From 3b0fa08fdd5052e15759c92263218449d0d1b5f7 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 10:59:20 +0200 Subject: [PATCH 45/46] Build README --- README.md | 8 ++++---- snippets/chunk-array.md | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e3d9727df..dd66eebff 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ * [Random integer in range](#random-integer-in-range) * [Random number in range](#random-number-in-range) * [Randomize order of array](#randomize-order-of-array) -* [Redirect to url](#redirect-to-url) +* [Redirect to URL](#redirect-to-url) * [Reverse a string](#reverse-a-string) * [RGB to hexadecimal](#rgb-to-hexadecimal) * [Run promises in series](#run-promises-in-series) @@ -189,14 +189,14 @@ const palindrome = str => { ### Chunk array -Use `Array.from(arrayLike[, mapFn[, thisArg]])` to create a new array, that fits the number of chunks that will be produced. -Use `mapFn` to map each element of the new array to a chunk the length of `size`. +Use `Array.from()` to create a new array, that fits the number of chunks that will be produced. +Use `Array.slice()` to map each element of the new array to a chunk the length of `size`. If the original array can't be split evenly, the final chunk will contain the remaining elements. ```js const chunk = (arr, size) => Array.from({length: Math.ceil(arr.length / size)}, (v, i) => arr.slice(i * size, i * size + size)); - // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] +// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` ### Compact diff --git a/snippets/chunk-array.md b/snippets/chunk-array.md index de6c5a568..c14bf269d 100644 --- a/snippets/chunk-array.md +++ b/snippets/chunk-array.md @@ -1,11 +1,11 @@ ### Chunk array -Use `Array.apply()` to create a new array, that fits the number of chunks that will be produced. -Use `Array.map()` to map each element of the new array to a chunk the length of `size`. +Use `Array.from()` to create a new array, that fits the number of chunks that will be produced. +Use `Array.slice()` to map each element of the new array to a chunk the length of `size`. If the original array can't be split evenly, the final chunk will contain the remaining elements. ```js const chunk = (arr, size) => - Array.apply(null, {length: Math.ceil(arr.length / size)}).map((v, i) => arr.slice(i * size, i * size + size)); + Array.from({length: Math.ceil(arr.length / size)}, (v, i) => arr.slice(i * size, i * size + size)); // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],5] ``` From f8d55631c6a5d9e4790d30347b45d675c1b0e10c Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 14 Dec 2017 11:10:47 +0200 Subject: [PATCH 46/46] 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] +```