Merge remote-tracking branch 'upstream/master'

This commit is contained in:
iamsoorena
2017-12-15 12:48:45 +03:30
90 changed files with 4340 additions and 509 deletions

View File

@ -1,11 +1,12 @@
### URL parameters
Use `match()` with an appropriate regular expression to get all key-value pairs, `map()` them appropriately.
Combine all key-value pairs into a single object using `Object.assign()` and the spread operator (`...`).
Use `match()` with an appropriate regular expression to get all key-value pairs, `Array.reduce()` to map and combine them into a single object.
Pass `location.search` as the argument to apply to the current `url`.
```js
const getUrlParameters = url =>
Object.assign(...url.match(/([^?=&]+)(=([^&]*))?/g).map(m => {[f,v] = m.split('='); return {[f]:v}}));
url.match(/([^?=&]+)(=([^&]*))/g).reduce(
(a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {}
);
// getUrlParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'}
```

View File

@ -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'

View File

@ -2,16 +2,14 @@
Use recursion.
For each letter in the given string, create all the partial anagrams for the rest of its letters.
Use `map()` to combine the letter with each partial anagram, then `reduce()` to combine all anagrams in one array.
Use `Array.map()` to combine the letter with each partial anagram, then `Array.reduce()` to combine all anagrams in one array.
Base cases are for string `length` equal to `2` or `1`.
```js
const anagrams = str => {
if(str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
return str.split('').reduce( (acc, letter, i) => {
anagrams(str.slice(0, i) + str.slice(i + 1)).map( val => acc.push(letter + val) );
return acc;
}, []);
}
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']
```

View File

@ -0,0 +1,8 @@
### Array concatenation
Use `Array.concat()` to concatenate an array with any additional arrays and/or values, specified in `args`.
```js
const arrayConcat = (arr, ...args) => arr.concat(...args);
// arrayConcat([1], 2, [3], [[4]]) -> [1,2,3,[4]]
```

View File

@ -0,0 +1,8 @@
### Array difference
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]
```

View File

@ -0,0 +1,8 @@
### Array intersection
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]
```

8
snippets/array-union.md Normal file
View File

@ -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]
```

View File

@ -1,9 +1,8 @@
### Average of array of numbers
Use `reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array.
Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array.
```js
const average = arr =>
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
```

View File

@ -0,0 +1,9 @@
### Bottom visible
Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of the page is visible.
```js
const bottomVisible = _ =>
document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight;
// bottomVisible() -> true
```

View File

@ -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'
```

View File

@ -0,0 +1,14 @@
### Chain asynchronous functions
Loop through an array of functions containing asynchronous events, calling `next` when each asynchronous event has completed.
```js
const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); };
/*
chainAsync([
next => { console.log('0 seconds'); setTimeout(next, 1000); },
next => { console.log('1 second'); setTimeout(next, 1000); },
next => { console.log('2 seconds'); }
])
*/
```

View File

@ -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
```

11
snippets/chunk-array.md Normal file
View File

@ -0,0 +1,11 @@
### Chunk array
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]
```

View File

@ -0,0 +1,9 @@
### Collatz algorithm
If `n` is even, return `n/2`. Otherwise return `3n+1`.
```js
const collatz = n => (n % 2 == 0) ? (n / 2) : (3 * n + 1);
// collatz(8) --> 4
// collatz(5) --> 16
```

8
snippets/compact.md Normal file
View File

@ -0,0 +1,8 @@
### Compact
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 ]
```

View File

@ -1,6 +1,6 @@
### Count occurrences of a value in array
Use `reduce()` to increment a counter each time you encounter the specific value inside the array.
Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array.
```js
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);

View File

@ -3,10 +3,13 @@
Use recursion.
If the number of provided arguments (`args`) is sufficient, call the passed function `f`.
Otherwise return a curried function `f` that expects the rest of the arguments.
If you want to curry a function that accepts a variable number of arguments (a variadic function, e.g. `Math.min()`), you can optionally pass the number of arguments to the second parameter `arity`.
```js
const curry = f =>
(...args) =>
args.length >= f.length ? f(...args) : (...otherArgs) => curry(f)(...args, ...otherArgs);
const curry = (fn, arity = fn.length, ...args) =>
arity <= args.length
? fn(...args)
: curry.bind(null, fn, arity, ...args);
// curry(Math.pow)(2)(10) -> 1024
// curry(Math.min, 3)(10)(50)(2) -> 2
```

View File

@ -1,10 +1,10 @@
### Deep flatten array
Use recursion.
Use `reduce()` to get all elements that are not arrays, flatten each element that is an array.
Use `Array.reduce()` to get all elements that are not arrays, flatten each element that is an array.
```js
const deepFlatten = arr =>
arr.reduce( (a, v) => a.concat( Array.isArray(v) ? flatten(v) : v ), []);
arr.reduce((a, v) => a.concat(Array.isArray(v) ? deepFlatten(v) : v), []);
// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5]
```

View File

@ -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]
```

View File

@ -0,0 +1,12 @@
### Drop elements in array
Loop through the array, using `Array.shift()` to drop the first element of the array until the returned value from the function is `true`.
Returns the remaining elements.
```js
const dropElements = (arr, func) => {
while (arr.length > 0 && !func(arr[0])) arr.shift();
return arr;
};
// dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4]
```

View File

@ -0,0 +1,19 @@
### Element is visible in viewport
Use `Element.getBoundingClientRect()` and the `window.inner(Width|Height)` values
to determine if a given element is visible in the viewport.
Omit the second argument to determine if the element is entirely visible, or specify `true` to determine if
it is partially visible.
```js
const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
const { top, left, bottom, right } = el.getBoundingClientRect();
return partiallyVisible
? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) &&
((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
: top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};
// e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10}
// elementIsVisibleInViewport(el) -> false (not fully visible)
// elementIsVisibleInViewport(el, true) -> true (partially visible)
```

View File

@ -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 a number is odd or even using the modulo (`%`) operator.
Returns `true` if the number is even, `false` if the number is odd.
```js
const isEven = num => Math.abs(num) % 2 === 0;
const isEven = num => num % 2 === 0;
// isEven(3) -> false
```

View File

@ -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]
```

10
snippets/fill-array.md Normal file
View File

@ -0,0 +1,10 @@
### Fill array
Use `Array.map()` to map values between `start` (inclusive) and `end` (exclusive) to `value`.
Omit `start` to start at the first element and/or `end` to finish at the last.
```js
const fillArray = (arr, value, start = 0, end = arr.length) =>
arr.map((v, i) => i >= start && i < end ? value : v);
// fillArray([1,2,3,4],'8',1,3) -> [1,'8','8',4]
```

View File

@ -1,8 +0,0 @@
### Filter out non-unique values in an array
Use `Array.filter()` for an array containing only the unique values.
```js
const unique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
// unique([1,2,2,3,4,4,5]) -> [1,3,5]
```

View File

@ -0,0 +1,8 @@
### Filter out non-unique values in an array
Use `Array.filter()` for an array containing only the unique values.
```js
const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5]
```

View File

@ -0,0 +1,13 @@
### Flatten array up to depth
Use recursion, decrementing `depth` by 1 for each level of depth.
Use `Array.reduce()` and `Array.concat()` to merge elements or arrays.
Base case, for `depth` equal to `1` stops recursion.
Omit the second element, `depth` to flatten only to a depth of `1` (single flatten).
```js
const flattenDepth = (arr, depth = 1) =>
depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), [])
: arr.reduce((a, v) => a.concat(v), []);
// flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5]
```

View File

@ -1,8 +1,8 @@
### Flatten array
Use `reduce()` to get all elements inside the array and `concat()` to flatten them.
Use `Array.reduce()` to get all elements inside the array and `concat()` to flatten them.
```js
const flatten = arr => arr.reduce( (a, v) => a.concat(v), []);
const flatten = arr => arr.reduce((a, v) => a.concat(v), []);
// flatten([1,[2],3,4]) -> [1,2,3,4]
```

View File

@ -0,0 +1,8 @@
### Get days difference between dates
Calculate the difference (in days) between to `Date` objects.
```js
const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24);
// getDaysDiffBetweenDates(new Date("2017-12-13"), new Date("2017-12-22")) -> 9
```

View File

@ -1,6 +1,6 @@
### Get max value from array
Use `Math.max()` combined with the spread operator (`...`) to get the minimum value in the array.
Use `Math.max()` combined with the spread operator (`...`) to get the maximum value in the array.
```js
const arrayMax = arr => Math.max(...arr);

View File

@ -0,0 +1,9 @@
### Get native type of value
Returns lower-cased constructor name of value, "undefined" or "null" if value is undefined or null
```js
const getType = v =>
v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase();
// getType(new Set([1,2,3])) -> "set"
```

View File

@ -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}
```

View File

@ -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
```

12
snippets/group-by.md Normal file
View File

@ -0,0 +1,12 @@
### Group by
Use `Array.map()` to map the values of an array to a function or property name.
Use `Array.reduce()` to create an object, where the keys are produced from the mapped results.
```js
const groupBy = (arr, func) =>
arr.map(typeof func === 'function' ? func : val => val[func])
.reduce((acc, val, i) => { acc[val] = (acc[val] || []).concat(arr[i]); return acc; }, {});
// groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]}
// groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']}
```

View File

@ -0,0 +1,10 @@
### Hamming distance
Use XOR operator (`^`) to find the bit difference between the two numbers, convert to binary string using `toString(2)`.
Count and return the number of `1`s in the string, using `match(/1/g)`.
```js
const hammingDistance = (num1, num2) =>
((num1 ^ num2).toString(2).match(/1/g) || '').length;
// hammingDistance(2,3) -> 1
```

View File

@ -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];

View File

@ -1,8 +1,8 @@
### 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);
const initial = arr => arr.slice(0, -1);
// initial([1,2,3]) -> [1,2]
```

View File

@ -1,10 +1,10 @@
### Initialize array with range
Use `Array(end-start)` to create an array of the desired length, `map()` to fill with the desired values in a range.
Use `Array(end-start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range.
You can omit `start` to use a default value of `0`.
```js
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]
```

9
snippets/is-array.md Normal file
View File

@ -0,0 +1,9 @@
### Is array
Use `Array.isArray()` to check if a value is classified as an array.
```js
const isArray = val => !!val && Array.isArray(val);
// isArray(null) -> false
// isArray([1]) -> true
```

9
snippets/is-boolean.md Normal file
View File

@ -0,0 +1,9 @@
### Is boolean
Use `typeof` to check if a value is classified as a boolean primitive.
```js
const isBoolean = val => typeof val === 'boolean';
// isBoolean(null) -> false
// isBoolean(false) -> true
```

9
snippets/is-function.md Normal file
View File

@ -0,0 +1,9 @@
### Is function
Use `typeof` to check if a value is classified as a function primitive.
```js
const isFunction = val => val && typeof val === 'function';
// isFunction('x') -> false
// isFunction(x => x) -> true
```

9
snippets/is-number.md Normal file
View File

@ -0,0 +1,9 @@
### Is number
Use `typeof` to check if a value is classified as a number primitive.
```js
const isNumber = val => typeof val === 'number';
// isNumber('1') -> false
// isNumber(1) -> true
```

9
snippets/is-string.md Normal file
View File

@ -0,0 +1,9 @@
### Is string
Use `typeof` to check if a value is classified as a string primitive.
```js
const isString = val => typeof val === 'string';
// isString(10) -> false
// isString('10') -> true
```

9
snippets/is-symbol.md Normal file
View File

@ -0,0 +1,9 @@
### Is symbol
Use `typeof` to check if a value is classified as a symbol primitive.
```js
const isSymbol = val => typeof val === 'symbol';
// isSymbol('x') -> false
// isSymbol(Symbol('x')) -> true
```

View File

@ -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];

View File

@ -1,13 +1,14 @@
### Measure time taken by function
Use `performance.now()` to get start and end time for the function, `console.log()` the time taken.
First argument is the function name, subsequent arguments are passed to the function.
Use `console.time()` and `console.timeEnd()` to measure the difference between the start and end times to determine how long the callback took to execute.
```js
const timeTaken = (func,...args) => {
var t0 = performance.now(), r = func(...args);
console.log(performance.now() - t0);
const timeTaken = callback => {
console.time('timeTaken');
const r = callback();
console.timeEnd('timeTaken');
return r;
}
// timeTaken(Math.pow, 2, 10) -> 1024 (0.010000000009313226 logged in console)
};
// timeTaken(() => Math.pow(2, 10)) -> 1024
// (logged): timeTaken: 0.02099609375ms
```

View File

@ -0,0 +1,13 @@
### Median of array of numbers
Find the middle of the array, use `Array.sort()` to sort the values.
Return the number at the midpoint if `length` is odd, otherwise the average of the two middle numbers.
```js
const median = arr => {
const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b);
return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
};
// median([5,6,50,1,-5]) -> 5
// median([0,10,-2,7]) -> 3.5
```

View File

@ -0,0 +1,11 @@
### Nth element of array
Use `Array.slice()` to get an array containing the nth element at the first place.
If the index is out of bounds, return `[]`.
Omit the second argument, `n`, to get the first element of the array.
```js
const nth = (arr, n=0) => (n>0? arr.slice(n,n+1) : arr.slice(n))[0];
// nth(['a','b','c'],1) -> 'b'
// nth(['a','b','b']-2) -> 'a'
```

View File

@ -0,0 +1,9 @@
### Number to array of digits
Convert the number to a string, use `split()` to convert build an array.
Use `Array.map()` and `parseInt()` to transform each value to an integer.
```js
const digitize = n => (''+n).split('').map(i => parseInt(i));
// digitize(2334) -> [2, 3, 3, 4]
```

View File

@ -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}
```

View File

@ -0,0 +1,8 @@
### 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]])
```

View File

@ -0,0 +1,15 @@
### 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"
```

10
snippets/percentile.md Normal file
View File

@ -0,0 +1,10 @@
### Percentile
Use `Array.reduce()` to calculate how many numbers are below the value and how many are the same value and
apply the percentile formula.
```js
const percentile = (arr, val) =>
100 * arr.reduce((acc,v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length;
// percentile([1,2,3,4,5,6,7,8,9,10], 6) -> 55
```

10
snippets/pick.md Normal file
View File

@ -0,0 +1,10 @@
### Pick
Use `Array.reduce()` to convert the filtered/picked keys back to a object with the corresponding key:value pair if the key exist in the obj.
```js
const pick = (obj, arr) =>
arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});
// pick({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c']) -> { 'a': 1, 'c': 3 }
// pick(object, ['a', 'c'])['a'] -> 1
```

View File

@ -1,9 +1,9 @@
### Powerset
Use `reduce()` combined with `map()` to iterate over elements and combine into an array containing all combinations.
Use `Array.reduce()` combined with `Array.map()` to iterate over elements and combine into an array containing all combinations.
```js
const powerset = arr =>
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]]
```

17
snippets/promisify.md Normal file
View File

@ -0,0 +1,17 @@
### Promisify
Use currying to return a function returning a `Promise` that calls the original function.
Use the `...rest` operator to pass in all the parameters.
*In Node 8+, you can use [`util.promisify`](https://nodejs.org/api/util.html#util_util_promisify_original)*
```js
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
```

View File

@ -0,0 +1,8 @@
### Random integer in range
Use `Math.random()` to generate a random number and map it to the desired range, using `Math.floor()` to make it an integer.
```js
const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
// randomIntegerInRange(0, 5) -> 2
```

View File

@ -1,8 +0,0 @@
### Randomize order of array
Use `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]
```

View File

@ -0,0 +1,9 @@
### Round number to n digits
Use `Math.round()` and template literals to round the number to the specified number of digits.
Omit the second argument, `decimals` to round to an integer.
```js
const round = (n, decimals=0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`);
// round(1.005, 2) -> 1.01
```

View File

@ -0,0 +1,9 @@
### Run promises in series
Run an array of promises in series using `Array.reduce()` by creating a promise chain, where each promise returns the next promise when resolved.
```js
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
```

View File

@ -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()
```

View File

@ -0,0 +1,12 @@
### Shallow clone object
Use the object `...spread` operator to spread the properties of the target object into the clone.
```js
const shallowClone = obj => ({ ...obj });
/*
const a = { x: true, y: 1 };
const b = shallowClone(a);
a === b -> false
*/
```

View File

@ -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]
```

View File

@ -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]
```

View File

@ -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.');
}
*/
```

View File

@ -1,9 +1,9 @@
### Sort characters in string (alphabetical)
Split the string using `split('')`, `sort()` utilizing `localeCompare()`, recombine using `join('')`.
Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, recombine using `join('')`.
```js
const sortCharactersInString = str =>
str.split('').sort( (a,b) => a.localeCompare(b) ).join('');
str.split('').sort((a, b) => a.localeCompare(b)).join('');
// sortCharactersInString('cabbage') -> 'aabbceg'
```

View File

@ -0,0 +1,15 @@
### Speech synthesis (experimental)
Use `SpeechSynthesisUtterance.voice` and `indow.speechSynthesis.getVoices()` to convert a message to speech.
Use `window.speechSynthesis.speak()` to play the message.
Learn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance).
```js
const speak = message => {
const msg = new SpeechSynthesisUtterance(message);
msg.voice = window.speechSynthesis.getVoices()[0];
window.speechSynthesis.speak(msg);
};
// speak('Hello, World') -> plays the message
```

View File

@ -0,0 +1,17 @@
### Standard deviation
Use `Array.reduce()` to calculate the mean, variance and the sum of the variance of the values, the variance of the values, then
determine the standard deviation.
You can omit the second argument to get the sample standard deviation or set it to `true` to get the population standard deviation.
```js
const standardDeviation = (arr, usePopulation = false) => {
const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length;
return Math.sqrt(
arr.reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), [])
.reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1))
);
};
// standardDeviation([10,2,38,23,38,23,21]) -> 13.284434142114991 (sample)
// standardDeviation([10,2,38,23,38,23,21], true) -> 12.29899614287479 (population)
```

View File

@ -1,8 +1,8 @@
### Sum of array of numbers
Use `reduce()` to add each value to an accumulator, initialized with a value of `0`.
Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`.
```js
const sum = arr => arr.reduce( (acc , val) => acc + val, 0);
const sum = arr => arr.reduce((acc, val) => acc + val, 0);
// sum([1,2,3,4]) -> 10
```

View File

@ -1,8 +1,9 @@
### Tail of list
Return `arr.slice(1)`.
Return `arr.slice(1)` if the array's `length` is more than `1`, otherwise return the whole array.
```js
const tail = arr => arr.slice(1);
const tail = arr => arr.length > 1 ? arr.slice(1) : arr;
// tail([1,2,3]) -> [2,3]
// tail([1]) -> [1]
```

9
snippets/take.md Normal file
View File

@ -0,0 +1,9 @@
### Take
Use `Array.slice()` to create a slice of the array with `n` elements taken from the beginning.
```js
const take = (arr, n = 1) => arr.slice(0, n);
// take([1, 2, 3], 5) -> [1, 2, 3]
// take([1, 2, 3], 0) -> []
```

View File

@ -0,0 +1,10 @@
### Truncate a String
Determine if the string's `length` is greater than `num`.
Return the string truncated to the desired length, with `...` appended to the end or the original string.
```js
const truncate = (str, num) =>
str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str;
// truncate('boomerang', 7) -> 'boom...'
```

View File

@ -0,0 +1,10 @@
### Validate email
Use a regular experssion to check if the email is valid.
Returns `true` if email is valid, `false` if not.
```js
const validateEmail = str =>
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(str);
// validateEmail(mymail@gmail.com) -> true
```

View File

@ -2,8 +2,9 @@
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
```

View File

@ -0,0 +1,8 @@
### Value or default
Returns value, or default value if passed value is `falsy`.
```js
const valueOrDefault = (value, d) => value || d;
// valueOrDefault(NaN, 30) -> 30
```