Nest all content into snippets

This commit is contained in:
Angelos Chalaris
2023-05-07 16:07:29 +03:00
parent 2ecadbada9
commit 6a45d2ec07
1240 changed files with 0 additions and 0 deletions

View File

@ -0,0 +1,25 @@
---
title: Partial sum array
type: snippet
language: javascript
tags: [math]
author: chalarangelo
cover: river-house-lights
dateModified: 2022-01-30T13:10:13+02:00
---
Creates an array of partial sums.
- Use `Array.prototype.reduce()`, initialized with an empty array accumulator to iterate over `nums`.
- Use `Array.prototype.slice()` to get the previous partial sum or `0` and add the current element to it.
- Use the spread operator (`...`) to add the new partial sum to the accumulator array containing the previous sums.
```js
const accumulate = (...nums) =>
nums.reduce((acc, n) => [...acc, n + (acc.slice(-1)[0] || 0)], []);
```
```js
accumulate(1, 2, 3, 4); // [1, 3, 6, 10]
accumulate(...[1, 2, 3, 4]); // [1, 3, 6, 10]
```

View File

@ -0,0 +1,22 @@
---
title: Add class to HTML element
type: snippet
language: javascript
tags: [browser]
author: chalarangelo
cover: budapest-palace
dateModified: 2020-12-30T19:21:15+02:00
---
Adds a class to an HTML element.
- Use `Element.classList` and `DOMTokenList.add()` to add the specified class to the element.
```js
const addClass = (el, className) => el.classList.add(className);
```
```js
addClass(document.querySelector('p'), 'special');
// The paragraph will now have the 'special' class
```

View File

@ -0,0 +1,27 @@
---
title: Add days to date
type: snippet
language: javascript
tags: [date]
cover: digital-nomad-12
dateModified: 2020-11-28T19:18:29+02:00
---
Calculates the date of `n` days from the given date, returning its string representation.
- Use the `Date` constructor to create a `Date` object from the first argument.
- Use `Date.prototype.getDate()` and `Date.prototype.setDate()` to add `n` days to the given date.
- Use `Date.prototype.toISOString()` to return a string in `yyyy-mm-dd` format.
```js
const addDaysToDate = (date, n) => {
const d = new Date(date);
d.setDate(d.getDate() + n);
return d.toISOString().split('T')[0];
};
```
```js
addDaysToDate('2020-10-15', 10); // '2020-10-25'
addDaysToDate('2020-10-15', -10); // '2020-10-05'
```

View File

@ -0,0 +1,28 @@
---
title: Add event listener to all targets
type: snippet
language: javascript
tags: [browser,event]
author: chalarangelo
cover: red-mountain
dateModified: 2021-04-22T08:53:29+03:00
---
Attaches an event listener to all the provided targets.
- Use `Array.prototype.forEach()` and `EventTarget.addEventListener()` to attach the provided `listener` for the given event `type` to all `targets`.
```js
const addEventListenerAll = (targets, type, listener, options, useCapture) => {
targets.forEach(target =>
target.addEventListener(type, listener, options, useCapture)
);
};
```
```js
addEventListenerAll(document.querySelectorAll('a'), 'click', () =>
console.log('Clicked a link')
);
// Logs 'Clicked a link' whenever any anchor element is clicked
```

View File

@ -0,0 +1,28 @@
---
title: Add minutes to date
type: snippet
language: javascript
tags: [date]
cover: lake-trees
dateModified: 2020-11-28T19:27:46+02:00
---
Calculates the date of `n` minutes from the given date, returning its string representation.
- Use the `Date` constructor to create a `Date` object from the first argument.
- Use `Date.prototype.getTime()` and `Date.prototype.setTime()` to add `n` minutes to the given date.
- Use `Date.prototype.toISOString()`, `String.prototype.split()` and `String.prototype.replace()` to return a string in `yyyy-mm-dd HH:MM:SS` format.
```js
const addMinutesToDate = (date, n) => {
const d = new Date(date);
d.setTime(d.getTime() + n * 60000);
return d.toISOString().split('.')[0].replace('T',' ');
};
```
```js
addMinutesToDate('2020-10-19 12:00:00', 10); // '2020-10-19 12:10:00'
addMinutesToDate('2020-10-19', -10); // '2020-10-18 23:50:00'
```

View File

@ -0,0 +1,28 @@
---
title: Add multiple listeners
type: snippet
language: javascript
tags: [browser,event]
cover: balloons
dateModified: 2020-10-22T20:23:47+03:00
---
Adds multiple event listeners with the same handler to an element.
- Use `Array.prototype.forEach()` and `EventTarget.addEventListener()` to add multiple event listeners with an assigned callback function to an element.
```js
const addMultipleListeners = (el, types, listener, options, useCapture) => {
types.forEach(type =>
el.addEventListener(type, listener, options, useCapture)
);
};
```
```js
addMultipleListeners(
document.querySelector('.my-element'),
['click', 'mousedown'],
() => { console.log('hello!') }
);
```

View File

@ -0,0 +1,25 @@
---
title: Add styles to HTML element
type: snippet
language: javascript
tags: [browser]
author: chalarangelo
cover: digital-nomad-14
dateModified: 2021-01-07T00:37:43+02:00
---
Adds the provided styles to the given HTML element.
- Use `Object.assign()` and `HTMLElement.style` to merge the provided `styles` object into the style of the given element.
```js
const addStyles = (el, styles) => Object.assign(el.style, styles);
```
```js
addStyles(document.getElementById('my-element'), {
background: 'red',
color: '#ffff00',
fontSize: '3rem'
});
```

View File

@ -0,0 +1,30 @@
---
title: Add weekdays to date
type: snippet
language: javascript
tags: [date]
cover: digital-nomad-9
dateModified: 2021-01-08T00:23:44+02:00
---
Calculates the date after adding the given number of business days.
- Use `Array.from()` to construct an array with `length` equal to the `count` of business days to be added.
- Use `Array.prototype.reduce()` to iterate over the array, starting from `startDate` and incrementing, using `Date.prototype.getDate()` and `Date.prototype.setDate()`.
- If the current `date` is on a weekend, update it again by adding either one day or two days to make it a weekday.
- **NOTE:** Does not take official holidays into account.
```js
const addWeekDays = (startDate, count) =>
Array.from({ length: count }).reduce(date => {
date = new Date(date.setDate(date.getDate() + 1));
if (date.getDay() % 6 === 0)
date = new Date(date.setDate(date.getDate() + (date.getDay() / 6 + 1)));
return date;
}, startDate);
```
```js
addWeekDays(new Date('Oct 09, 2020'), 5); // 'Oct 16, 2020'
addWeekDays(new Date('Oct 12, 2020'), 5); // 'Oct 19, 2020'
```

View File

@ -0,0 +1,26 @@
---
title: Check if array elements are equal based on function
type: snippet
language: javascript
tags: [array]
cover: orange-coffee-2
dateModified: 2020-10-19T22:14:49+03:00
---
Checks if all elements in an array are equal, based on the provided mapping function.
- Apply `fn` to the first element of `arr`.
- Use `Array.prototype.every()` to check if `fn` returns the same value for all elements in the array as it did for the first one.
- Elements in the array are compared using the strict comparison operator, which does not account for `NaN` self-inequality.
```js
const allEqualBy = (arr, fn) => {
const eql = fn(arr[0]);
return arr.every(val => fn(val) === eql);
};
```
```js
allEqualBy([1.1, 1.2, 1.3], Math.round); // true
allEqualBy([1.1, 1.3, 1.6], Math.round); // false
```

View File

@ -0,0 +1,22 @@
---
title: Check if array elements are equal
type: snippet
language: javascript
tags: [array]
cover: shelf-plant
dateModified: 2020-10-18T20:24:28+03:00
---
Checks if all elements in an array are equal.
- Use `Array.prototype.every()` to check if all the elements of the array are the same as the first one.
- Elements in the array are compared using the strict comparison operator, which does not account for `NaN` self-inequality.
```js
const allEqual = arr => arr.every(val => val === arr[0]);
```
```js
allEqual([1, 2, 3, 4, 5, 6]); // false
allEqual([1, 1, 1, 1]); // true
```

View File

@ -0,0 +1,23 @@
---
title: Check if all array elements are unique based on function
type: snippet
language: javascript
tags: [array]
cover: digital-nomad-10
dateModified: 2021-01-08T00:23:44+02:00
---
Checks if all elements in an array are unique, based on the provided mapping function.
- Use `Array.prototype.map()` to apply `fn` to all elements in `arr`.
- Create a new `Set` from the mapped values to keep only unique occurrences.
- Use `Array.prototype.length` and `Set.prototype.size` to compare the length of the unique mapped values to the original array.
```js
const allUniqueBy = (arr, fn) => arr.length === new Set(arr.map(fn)).size;
```
```js
allUniqueBy([1.2, 2.4, 2.9], Math.round); // true
allUniqueBy([1.2, 2.3, 2.4], Math.round); // false
```

View File

@ -0,0 +1,22 @@
---
title: Check if all array elements are unique
type: snippet
language: javascript
tags: [array]
cover: jars-on-shelf
dateModified: 2021-01-08T00:23:44+02:00
---
Checks if all elements in an array are unique.
- Create a new `Set` from the mapped values to keep only unique occurrences.
- Use `Array.prototype.length` and `Set.prototype.size` to compare the length of the unique values to the original array.
```js
const allUnique = arr => arr.length === new Set(arr).size;
```
```js
allUnique([1, 2, 3, 4]); // true
allUnique([1, 1, 2, 3]); // false
```

22
snippets/js/s/all.md Normal file
View File

@ -0,0 +1,22 @@
---
title: Test if all array elements are truthy
type: snippet
language: javascript
tags: [array]
cover: touch-flower
dateModified: 2020-10-18T20:24:28+03:00
---
Checks if the provided predicate function returns `true` for all elements in a collection.
- Use `Array.prototype.every()` to test if all elements in the collection return `true` based on `fn`.
- Omit the second argument, `fn`, to use `Boolean` as a default.
```js
const all = (arr, fn = Boolean) => arr.every(fn);
```
```js
all([4, 2, 3], x => x > 1); // true
all([1, 2, 3]); // true
```

View File

@ -0,0 +1,31 @@
---
title: Sort array alphabetically
type: snippet
language: javascript
tags: [array]
author: chalarangelo
cover: boutique-home-office-1
dateModified: 2023-02-15T05:00:00-04:00
---
Sorts an array of objects alphabetically based on a given property.
- Use `Array.prototype.sort()` to sort the array based on the given property.
- Use `String.prototype.localeCompare()` to compare the values for the given property.
```js
const alphabetical = (arr, getter, order = 'asc') =>
arr.sort(
order === 'desc'
? (a, b) => getter(b).localeCompare(getter(a))
: (a, b) => getter(a).localeCompare(getter(b))
);
```
```js
const people = [ { name: 'John' }, { name: 'Adam' }, { name: 'Mary' } ];
alphabetical(people, g => g.name);
// [ { name: 'Adam' }, { name: 'John' }, { name: 'Mary' } ]
alphabetical(people, g => g.name, 'desc');
// [ { name: 'Mary' }, { name: 'John' }, { name: 'Adam' } ]
```

23
snippets/js/s/and.md Normal file
View File

@ -0,0 +1,23 @@
---
title: Logical and
type: snippet
language: javascript
tags: [math,logic]
unlisted: true
cover: succulent-1
dateModified: 2021-01-04T13:04:15+02:00
---
Checks if both arguments are `true`.
- Use the logical and (`&&`) operator on the two given values.
```js
const and = (a, b) => a && b;
```
```js
and(true, true); // true
and(true, false); // false
and(false, false); // false
```

22
snippets/js/s/any.md Normal file
View File

@ -0,0 +1,22 @@
---
title: Test if any array element is truthy
type: snippet
language: javascript
tags: [array]
cover: basket-paper
dateModified: 2020-10-18T20:24:28+03:00
---
Checks if the provided predicate function returns `true` for at least one element in a collection.
- Use `Array.prototype.some()` to test if any elements in the collection return `true` based on `fn`.
- Omit the second argument, `fn`, to use `Boolean` as a default.
```js
const any = (arr, fn = Boolean) => arr.some(fn);
```
```js
any([0, 1, 2, 0], x => x >= 2); // true
any([0, 0, 1, 0]); // true
```

28
snippets/js/s/aperture.md Normal file
View File

@ -0,0 +1,28 @@
---
title: Consecutive element subarrays
type: snippet
language: javascript
tags: [array]
author: chalarangelo
cover: camera-zoom
dateModified: 2020-10-18T20:24:28+03:00
---
Creates an array of `n`-tuples of consecutive elements.
- Use `Array.prototype.slice()` and `Array.prototype.map()` to create an array of appropriate length.
- Populate the array with `n`-tuples of consecutive elements from `arr`.
- If `n` is greater than the length of `arr`, return an empty array.
```js
const aperture = (n, arr) =>
n > arr.length
? []
: arr.slice(n - 1).map((v, i) => arr.slice(i, i + n));
```
```js
aperture(2, [1, 2, 3, 4]); // [[1, 2], [2, 3], [3, 4]]
aperture(3, [1, 2, 3, 4]); // [[1, 2, 3], [2, 3, 4]]
aperture(5, [1, 2, 3, 4]); // []
```

View File

@ -0,0 +1,22 @@
---
title: Approximate number equality
type: snippet
language: javascript
tags: [math]
cover: engine
dateModified: 2020-11-01T20:50:57+02:00
---
Checks if two numbers are approximately equal to each other.
- Use `Math.abs()` to compare the absolute difference of the two values to `epsilon`.
- Omit the third argument, `epsilon`, to use a default value of `0.001`.
```js
const approximatelyEqual = (v1, v2, epsilon = 0.001) =>
Math.abs(v1 - v2) < epsilon;
```
```js
approximatelyEqual(Math.PI / 2.0, 1.5708); // true
```

View File

@ -0,0 +1,21 @@
---
title: Arithmetic progression
type: snippet
language: javascript
tags: [math,algorithm]
cover: u-got-this
dateModified: 2021-10-13T19:29:39+02:00
---
Creates an array of numbers in the arithmetic progression, starting with the given positive integer and up to the specified limit.
- Use `Array.from()` to create an array of the desired length, `lim / n`. Use a map function to fill it with the desired values in the given range.
```js
const arithmeticProgression = (n, lim) =>
Array.from({ length: Math.ceil(lim / n) }, (_, i) => (i + 1) * n );
```
```js
arithmeticProgression(5, 25); // [5, 10, 15, 20, 25]
```

View File

@ -0,0 +1,30 @@
---
title: Array to CSV
type: snippet
language: javascript
tags: [array,string]
cover: sunrise-over-city
dateModified: 2020-11-03T21:55:08+02:00
---
Converts a 2D array to a comma-separated values (CSV) string.
- Use `Array.prototype.map()` and `Array.prototype.join()` to combine individual 1D arrays (rows) into strings, using the provided `delimiter`.
- Use `Array.prototype.join()` to combine all rows into a CSV string, separating each row with a newline (`\n`).
- Omit the second argument, `delimiter`, to use a default delimiter of `,`.
```js
const arrayToCSV = (arr, delimiter = ',') =>
arr
.map(v =>
v.map(x => (isNaN(x) ? `"${x.replace(/"/g, '""')}"` : x)).join(delimiter)
)
.join('\n');
```
```js
arrayToCSV([['a', 'b'], ['c', 'd']]); // '"a","b"\n"c","d"'
arrayToCSV([['a', 'b'], ['c', 'd']], ';'); // '"a";"b"\n"c";"d"'
arrayToCSV([['a', '"b" great'], ['c', 3.1415]]);
// '"a","""b"" great"\n"c",3.1415'
```

View File

@ -0,0 +1,23 @@
---
title: Array to HTML list
type: snippet
language: javascript
tags: [browser,array]
cover: red-succulent
dateModified: 2020-10-20T11:46:23+03:00
---
Converts the given array elements into `<li>` tags and appends them to the list of the given id.
- Use `Array.prototype.map()` and `Document.querySelector()` to create a list of html tags.
```js
const arrayToHTMLList = (arr, listID) =>
document.querySelector(`#${listID}`).innerHTML += arr
.map(item => `<li>${item}</li>`)
.join('');
```
```js
arrayToHTMLList(['item 1', 'item 2'], 'myListID');
```

21
snippets/js/s/ary.md Normal file
View File

@ -0,0 +1,21 @@
---
title: Function arity
type: snippet
language: javascript
tags: [function]
cover: trippy-chemicals
dateModified: 2020-10-18T20:24:28+03:00
---
Creates a function that accepts up to `n` arguments, ignoring any additional arguments.
- Call the provided function, `fn`, with up to `n` arguments, using `Array.prototype.slice()` and the spread operator (`...`).
```js
const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
```
```js
const firstTwoMax = ary(Math.max, 2);
[[2, 6, 'a'], [6, 4, 8], [10]].map(x => firstTwoMax(...x)); // [6, 6, 10]
```

View File

@ -0,0 +1,24 @@
---
title: Assert object keys are valid
type: snippet
language: javascript
tags: [object]
author: chalarangelo
cover: river-flow
dateModified: 2021-07-18T05:00:00-04:00
---
Validates all keys in an object match the given `keys`.
- Use `Object.keys()` to get the keys of the given object, `obj`.
- Use `Array.prototype.every()` and `Array.prototype.includes()` to validate that each key in the object is specified in the `keys` array.
```js
const assertValidKeys = (obj, keys) =>
Object.keys(obj).every(key => keys.includes(key));
```
```js
assertValidKeys({ id: 10, name: 'apple' }, ['id', 'name']); // true
assertValidKeys({ id: 10, name: 'apple' }, ['id', 'type']); // false
```

21
snippets/js/s/atob.md Normal file
View File

@ -0,0 +1,21 @@
---
title: Decode Base64 encoded string
type: snippet
language: javascript
tags: [node,string]
cover: thread
dateModified: 2020-09-15T16:28:04+03:00
---
Decodes a string of data which has been encoded using base-64 encoding.
- Create a `Buffer` for the given string with base-64 encoding.
- Use `Buffer.prototype.toString()` to return the decoded string.
```js
const atob = str => Buffer.from(str, 'base64').toString('binary');
```
```js
atob('Zm9vYmFy'); // 'foobar'
```

30
snippets/js/s/attempt.md Normal file
View File

@ -0,0 +1,30 @@
---
title: Attempt invoking a function
type: snippet
language: javascript
tags: [function]
cover: spanish-resort
dateModified: 2020-10-18T20:24:28+03:00
---
Attempts to invoke a function with the provided arguments, returning either the result or the caught error object.
- Use a `try...catch` block to return either the result of the function or an appropriate error.
- If the caught object is not an `Error`, use it to create a new `Error`.
```js
const attempt = (fn, ...args) => {
try {
return fn(...args);
} catch (e) {
return e instanceof Error ? e : new Error(e);
}
};
```
```js
var elements = attempt(function(selector) {
return document.querySelectorAll(selector);
}, '>_>');
if (elements instanceof Error) elements = []; // elements = []
```

View File

@ -0,0 +1,26 @@
---
title: Mapped array average
type: snippet
language: javascript
tags: [math]
cover: rock-climbing
dateModified: 2020-10-21T21:17:45+03:00
---
Calculates the average of an array, after mapping each element to a value using the provided function.
- Use `Array.prototype.map()` to map each element to the value returned by `fn`.
- Use `Array.prototype.reduce()` to add each value to an accumulator, initialized with a value of `0`.
- Divide the resulting array by its length.
```js
const averageBy = (arr, fn) =>
arr
.map(typeof fn === 'function' ? fn : val => val[fn])
.reduce((acc, val) => acc + val, 0) / arr.length;
```
```js
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 5
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 5
```

23
snippets/js/s/average.md Normal file
View File

@ -0,0 +1,23 @@
---
title: Average of numbers
type: snippet
language: javascript
tags: [math]
cover: interior-8
dateModified: 2020-10-22T20:23:47+03:00
---
Calculates the average of two or more numbers.
- Use `Array.prototype.reduce()` to add each value to an accumulator, initialized with a value of `0`.
- Divide the resulting array by its length.
```js
const average = (...nums) =>
nums.reduce((acc, val) => acc + val, 0) / nums.length;
```
```js
average(...[1, 2, 3]); // 2
average(1, 2, 3); // 2
```

View File

@ -0,0 +1,26 @@
---
title: Bifurcate array based on function
type: snippet
language: javascript
tags: [array]
cover: canoe
dateModified: 2020-11-01T20:50:57+02:00
---
Splits values into two groups, based on the result of the given filtering function.
- Use `Array.prototype.reduce()` and `Array.prototype.push()` to add elements to groups, based on the value returned by `fn` for each element.
- If `fn` returns a truthy value for any element, add it to the first group, otherwise add it to the second group.
```js
const bifurcateBy = (arr, fn) =>
arr.reduce((acc, val, i) => (acc[fn(val, i) ? 0 : 1].push(val), acc), [
[],
[],
]);
```
```js
bifurcateBy(['beep', 'boop', 'foo', 'bar'], x => x[0] === 'b');
// [ ['beep', 'boop', 'bar'], ['foo'] ]
```

View File

@ -0,0 +1,26 @@
---
title: Bifurcate array based on values
type: snippet
language: javascript
tags: [array]
cover: two-cities
dateModified: 2020-11-01T20:50:57+02:00
---
Splits values into two groups, based on the result of the given `filter` array.
- Use `Array.prototype.reduce()` and `Array.prototype.push()` to add elements to groups, based on `filter`.
- If `filter` has a truthy value for any element, add it to the first group, otherwise add it to the second group.
```js
const bifurcate = (arr, filter) =>
arr.reduce((acc, val, i) => (acc[filter[i] ? 0 : 1].push(val), acc), [
[],
[],
]);
```
```js
bifurcate(['beep', 'boop', 'foo', 'bar'], [true, true, false, true]);
// [ ['beep', 'boop', 'bar'], ['foo'] ]
```

View File

@ -0,0 +1,37 @@
---
title: Binary search
type: snippet
language: javascript
tags: [algorithm,array]
author: chalarangelo
cover: zen-indoors
dateModified: 2020-12-29T13:06:47+02:00
---
Finds the index of a given element in a sorted array using the binary search algorithm.
- Declare the left and right search boundaries, `l` and `r`, initialized to `0` and the `length` of the array respectively.
- Use a `while` loop to repeatedly narrow down the search subarray, using `Math.floor()` to cut it in half.
- Return the index of the element if found, otherwise return `-1`.
- **Note:** Does not account for duplicate values in the array.
```js
const binarySearch = (arr, item) => {
let l = 0,
r = arr.length - 1;
while (l <= r) {
const mid = Math.floor((l + r) / 2);
const guess = arr[mid];
if (guess === item) return mid;
if (guess > item) r = mid - 1;
else l = mid + 1;
}
return -1;
};
```
```js
binarySearch([1, 2, 3, 4, 5], 1); // 0
binarySearch([1, 2, 3, 4, 5], 5); // 4
binarySearch([1, 2, 3, 4, 5], 6); // -1
```

21
snippets/js/s/binary.md Normal file
View File

@ -0,0 +1,21 @@
---
title: Binary function arity
type: snippet
language: javascript
tags: [function]
author: chalarangelo
cover: blue-bird
dateModified: 2020-10-18T23:04:45+03:00
---
Creates a function that accepts up to two arguments, ignoring any additional arguments.
- Call the provided function, `fn`, with the first two arguments given.
```js
const binary = fn => (a, b) => fn(a, b);
```
```js
['2', '1', '0'].map(binary(Math.max)); // [2, 1, 2]
```

37
snippets/js/s/bind-all.md Normal file
View File

@ -0,0 +1,37 @@
---
title: Bind all object methods
type: snippet
language: javascript
tags: [object,function]
cover: laptop-with-code
dateModified: 2020-11-03T22:11:18+02:00
---
Binds methods of an object to the object itself, overwriting the existing method.
- Use `Array.prototype.forEach()` to iterate over the given `fns`.
- Return a function for each one, using `Function.prototype.apply()` to apply the given context (`obj`) to `fn`.
```js
const bindAll = (obj, ...fns) =>
fns.forEach(
fn => (
(f = obj[fn]),
(obj[fn] = function() {
return f.apply(obj);
})
)
);
```
```js
var view = {
label: 'docs',
click: function() {
console.log('clicked ' + this.label);
}
};
bindAll(view, 'click');
document.body.addEventListener('click', view.click);
// Log 'clicked docs' when clicked.
```

30
snippets/js/s/bind-key.md Normal file
View File

@ -0,0 +1,30 @@
---
title: Bind object method
type: snippet
language: javascript
tags: [function,object]
cover: oven-paddle
excerpt: Creates a function that invokes a method at a key in an object, with optional additional parameters.
dateModified: 2020-10-18T23:04:45+03:00
---
Creates a function that invokes the method at a given key of an object, optionally prepending any additional supplied parameters to the arguments.
- Return a `function` that uses `Function.prototype.apply()` to bind `context[fn]` to `context`.
- Use the spread operator (`...`) to prepend any additional supplied parameters to the arguments.
```js
const bindKey = (context, fn, ...boundArgs) => (...args) =>
context[fn].apply(context, [...boundArgs, ...args]);
```
```js
const freddy = {
user: 'fred',
greet: function(greeting, punctuation) {
return greeting + ' ' + this.user + punctuation;
}
};
const freddyBound = bindKey(freddy, 'greet');
console.log(freddyBound('hi', '!')); // 'hi fred!'
```

27
snippets/js/s/bind.md Normal file
View File

@ -0,0 +1,27 @@
---
title: Bind function context
type: snippet
language: javascript
tags: [function,object]
cover: tranquility
dateModified: 2020-10-18T23:04:45+03:00
---
Creates a function that invokes `fn` with a given context, optionally prepending any additional supplied parameters to the arguments.
- Return a `function` that uses `Function.prototype.apply()` to apply the given `context` to `fn`.
- Use the spread operator (`...`) to prepend any additional supplied parameters to the arguments.
```js
const bind = (fn, context, ...boundArgs) => (...args) =>
fn.apply(context, [...boundArgs, ...args]);
```
```js
function greet(greeting, punctuation) {
return greeting + ' ' + this.user + punctuation;
}
const freddy = { user: 'fred' };
const freddyBound = bind(greet, freddy);
console.log(freddyBound('hi', '!')); // 'hi fred!'
```

View File

@ -0,0 +1,33 @@
---
title: Binomial coefficient
type: snippet
language: javascript
tags: [math,algorithm]
cover: blue-red-mountain
dateModified: 2020-12-28T13:49:24+02:00
---
Calculates the number of ways to choose `k` items from `n` items without repetition and without order.
- Use `Number.isNaN()` to check if any of the two values is `NaN`.
- Check if `k` is less than `0`, greater than or equal to `n`, equal to `1` or `n - 1` and return the appropriate result.
- Check if `n - k` is less than `k` and switch their values accordingly.
- Loop from `2` through `k` and calculate the binomial coefficient.
- Use `Math.round()` to account for rounding errors in the calculation.
```js
const binomialCoefficient = (n, k) => {
if (Number.isNaN(n) || Number.isNaN(k)) return NaN;
if (k < 0 || k > n) return 0;
if (k === 0 || k === n) return 1;
if (k === 1 || k === n - 1) return n;
if (n - k < k) k = n - k;
let res = n;
for (let j = 2; j <= k; j++) res *= (n - j + 1) / j;
return Math.round(res);
};
```
```js
binomialCoefficient(8, 2); // 28
```

25
snippets/js/s/both.md Normal file
View File

@ -0,0 +1,25 @@
---
title: Logical and for functions
type: snippet
language: javascript
tags: [function,logic]
unlisted: true
cover: succulent-2
dateModified: 2021-01-04T13:04:15+02:00
---
Checks if both of the given functions return `true` for a given set of arguments.
- Use the logical and (`&&`) operator on the result of calling the two functions with the supplied `args`.
```js
const both = (f, g) => (...args) => f(...args) && g(...args);
```
```js
const isEven = num => num % 2 === 0;
const isPositive = num => num > 0;
const isPositiveEven = both(isEven, isPositive);
isPositiveEven(4); // true
isPositiveEven(-2); // false
```

View File

@ -0,0 +1,23 @@
---
title: Check if bottom of page is visible
type: snippet
language: javascript
tags: [browser]
cover: red-mountain
dateModified: 2020-10-22T20:23:47+03:00
---
Checks if the bottom of the page is visible.
- Use `Window.scrollY`, `Element.scrollHeight` and `Element.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);
```
```js
bottomVisible(); // true
```

21
snippets/js/s/btoa.md Normal file
View File

@ -0,0 +1,21 @@
---
title: Encode string to Base64
type: snippet
language: javascript
tags: [node,string]
cover: laptop-journey
dateModified: 2020-09-15T16:28:04+03:00
---
Creates a base-64 encoded ASCII string from a String object in which each character in the string is treated as a byte of binary data.
- Create a `Buffer` for the given string with binary encoding.
- Use `Buffer.prototype.toString()` to return the base-64 encoded string.
```js
const btoa = str => Buffer.from(str, 'binary').toString('base64');
```
```js
btoa('foobar'); // 'Zm9vYmFy'
```

View File

@ -0,0 +1,38 @@
---
title: Bubble sort
type: snippet
language: javascript
tags: [algorithm,array]
cover: budapest-palace
dateModified: 2020-12-29T12:18:58+02:00
---
Sorts an array of numbers, using the bubble sort algorithm.
- Declare a variable, `swapped`, that indicates if any values were swapped during the current iteration.
- Use the spread operator (`...`) to clone the original array, `arr`.
- Use a `for` loop to iterate over the elements of the cloned array, terminating before the last element.
- Use a nested `for` loop to iterate over the segment of the array between `0` and `i`, swapping any adjacent out of order elements and setting `swapped` to `true`.
- If `swapped` is `false` after an iteration, no more changes are needed, so the cloned array is returned.
```js
const bubbleSort = arr => {
let swapped = false;
const a = [...arr];
for (let i = 1; i < a.length; i++) {
swapped = false;
for (let j = 0; j < a.length - i; j++) {
if (a[j + 1] < a[j]) {
[a[j], a[j + 1]] = [a[j + 1], a[j]];
swapped = true;
}
}
if (!swapped) return a;
}
return a;
};
```
```js
bubbleSort([2, 1, 4, 3]); // [1, 2, 3, 4]
```

View File

@ -0,0 +1,34 @@
---
title: Bucket sort
type: snippet
language: javascript
tags: [algorithm,array]
cover: canoe
dateModified: 2020-12-29T12:22:44+02:00
---
Sorts an array of numbers, using the bucket sort algorithm.
- Use `Math.min()`, `Math.max()` and the spread operator (`...`) to find the minimum and maximum values of the given array.
- Use `Array.from()` and `Math.floor()` to create the appropriate number of `buckets` (empty arrays).
- Use `Array.prototype.forEach()` to populate each bucket with the appropriate elements from the array.
- Use `Array.prototype.reduce()`, the spread operator (`...`) and `Array.prototype.sort()` to sort each bucket and append it to the result.
```js
const bucketSort = (arr, size = 5) => {
const min = Math.min(...arr);
const max = Math.max(...arr);
const buckets = Array.from(
{ length: Math.floor((max - min) / size) + 1 },
() => []
);
arr.forEach(val => {
buckets[Math.floor((val - min) / size)].push(val);
});
return buckets.reduce((acc, b) => [...acc, ...b.sort((a, b) => a - b)], []);
};
```
```js
bucketSort([6, 3, 4, 1]); // [1, 3, 4, 6]
```

View File

@ -0,0 +1,22 @@
---
title: Byte size of string
type: snippet
language: javascript
tags: [string]
cover: mountain-lake-cottage-2
dateModified: 2020-10-18T23:04:45+03:00
---
Returns the length of a string in bytes.
- Convert a given string to a [`Blob` Object](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
- Use `Blob.size` to get the length of the string in bytes.
```js
const byteSize = str => new Blob([str]).size;
```
```js
byteSize('😀'); // 4
byteSize('Hello World'); // 11
```

View File

@ -0,0 +1,38 @@
---
title: Caesar cipher
type: snippet
language: javascript
tags: [algorithm,string]
cover: ancient-greek-building
dateModified: 2020-12-29T12:29:21+02:00
---
Encrypts or decrypts a given string using the Caesar cipher.
- Use the modulo (`%`) operator and the ternary operator (`?`) to calculate the correct encryption/decryption key.
- Use the spread operator (`...`) and `Array.prototype.map()` to iterate over the letters of the given string.
- Use `String.prototype.charCodeAt()` and `String.fromCharCode()` to convert each letter appropriately, ignoring special characters, spaces etc.
- Use `Array.prototype.join()` to combine all the letters into a string.
- Pass `true` to the last parameter, `decrypt`, to decrypt an encrypted string.
```js
const caesarCipher = (str, shift, decrypt = false) => {
const s = decrypt ? (26 - shift) % 26 : shift;
const n = s > 0 ? s : 26 + (s % 26);
return [...str]
.map((l, i) => {
const c = str.charCodeAt(i);
if (c >= 65 && c <= 90)
return String.fromCharCode(((c - 65 + n) % 26) + 65);
if (c >= 97 && c <= 122)
return String.fromCharCode(((c - 97 + n) % 26) + 97);
return l;
})
.join('');
};
```
```js
caesarCipher('Hello World!', -3); // 'Ebiil Tloia!'
caesarCipher('Ebiil Tloia!', 23, true); // 'Hello World!'
```

View File

@ -0,0 +1,24 @@
---
title: Call or return
type: snippet
language: javascript
tags: [function]
author: chalarangelo
cover: cows
dateModified: 2022-04-04T05:00:00-04:00
---
Calls the argument if it's a function, otherwise returns it.
- Use the `typeof` operator to check if the given argument is a function.
- If it is, use the spread operator (`...`) to call it with the rest of the given arguments. Otherwise, return it.
```js
const callOrReturn = (fn, ...args) =>
typeof fn === 'function' ? fn(...args) : fn;
```
```js
callOrReturn(x => x + 1, 1); // 2
callOrReturn(1, 1); // 1
```

26
snippets/js/s/call.md Normal file
View File

@ -0,0 +1,26 @@
---
title: Call functions with context
type: snippet
language: javascript
tags: [function]
cover: rabbit-call
dateModified: 2021-06-13T13:50:25+03:00
---
Given a key and a set of arguments, call them when given a context.
- Use a closure to call `key` with `args` for the given `context`.
```js
const call = (key, ...args) => context => context[key](...args);
```
```js
Promise.resolve([1, 2, 3])
.then(call('map', x => 2 * x))
.then(console.log); // [ 2, 4, 6 ]
const map = call.bind(null, 'map');
Promise.resolve([1, 2, 3])
.then(map(x => 2 * x))
.then(console.log); // [ 2, 4, 6 ]
```

View File

@ -0,0 +1,21 @@
---
title: Capitalize every word
type: snippet
language: javascript
tags: [string,regexp]
cover: laptop-plants
dateModified: 2020-10-22T20:23:47+03:00
---
Capitalizes the first letter of every word in a string.
- Use `String.prototype.replace()` to match the first character of each word and `String.prototype.toUpperCase()` to capitalize it.
```js
const capitalizeEveryWord = str =>
str.replace(/\b[a-z]/g, char => char.toUpperCase());
```
```js
capitalizeEveryWord('hello world!'); // 'Hello World!'
```

View File

@ -0,0 +1,25 @@
---
title: Capitalize string
type: snippet
language: javascript
tags: [string]
cover: digital-nomad-3
dateModified: 2020-11-01T20:50:57+02:00
---
Capitalizes the first letter of a string.
- Use array destructuring and `String.prototype.toUpperCase()` to capitalize the first letter of the string.
- Use `Array.prototype.join()` to combine the capitalized `first` with the `...rest` of the characters.
- Omit the `lowerRest` argument to keep the rest of the string intact, or set it to `true` to convert to lowercase.
```js
const capitalize = ([first, ...rest], lowerRest = false) =>
first.toUpperCase() +
(lowerRest ? rest.join('').toLowerCase() : rest.join(''));
```
```js
capitalize('fooBar'); // 'FooBar'
capitalize('fooBar', true); // 'Foobar'
```

View File

@ -0,0 +1,22 @@
---
title: Cartesian product
type: snippet
language: javascript
tags: [math]
cover: sail-away
dateModified: 2020-12-29T12:31:43+02:00
---
Calculates the cartesian product of two arrays.
- Use `Array.prototype.reduce()`, `Array.prototype.map()` and the spread operator (`...`) to generate all possible element pairs from the two arrays.
```js
const cartesianProduct = (a, b) =>
a.reduce((p, x) => [...p, ...b.map(y => [x, y])], []);
```
```js
cartesianProduct(['x', 'y'], [1, 2]);
// [['x', 1], ['x', 2], ['y', 1], ['y', 2]]
```

View File

@ -0,0 +1,21 @@
---
title: Cast to array
type: snippet
language: javascript
tags: [type,array]
cover: man-red-sunset
dateModified: 2020-09-15T16:28:04+03:00
---
Casts the provided value as an array if it's not one.
- Use `Array.isArray()` to determine if `val` is an array and return it as-is or encapsulated in an array accordingly.
```js
const castArray = val => (Array.isArray(val) ? val : [val]);
```
```js
castArray('foo'); // ['foo']
castArray([1]); // [1]
```

View File

@ -0,0 +1,21 @@
---
title: Celsius to Fahrenheit
type: snippet
language: javascript
tags: [math]
unlisted: true
cover: last-light
dateModified: 2021-01-04T13:04:15+02:00
---
Converts Celsius to Fahrenheit.
- Follow the conversion formula `F = 1.8 * C + 32`.
```js
const celsiusToFahrenheit = degrees => 1.8 * degrees + 32;
```
```js
celsiusToFahrenheit(33); // 91.4
```

View File

@ -0,0 +1,40 @@
---
title: Chain async functions
type: snippet
language: javascript
tags: [function]
cover: tram-car
dateModified: 2020-09-15T16:28:04+03:00
---
Chains 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 last = fns[fns.length - 1];
const next = () => {
const fn = fns[curr++];
fn === last ? fn() : fn(next);
};
next();
};
```
```js
chainAsync([
next => {
console.log('0 seconds');
setTimeout(next, 1000);
},
next => {
console.log('1 second');
setTimeout(next, 1000);
},
() => {
console.log('2 second');
}
]);
```

View File

@ -0,0 +1,33 @@
---
title: Change color lightness
type: snippet
language: javascript
tags: [string,browser,regexp]
cover: aerial-view-port
dateModified: 2020-10-31T16:37:54+02:00
---
Changes the lightness value of an `hsl()` color string.
- Use `String.prototype.match()` to get an array of 3 strings with the numeric values.
- Use `Array.prototype.map()` in combination with `Number` to convert them into an array of numeric values.
- Make sure the lightness is within the valid range (between `0` and `100`), using `Math.max()` and `Math.min()`.
- Use a template literal to create a new `hsl()` string with the updated value.
```js
const changeLightness = (delta, hslStr) => {
const [hue, saturation, lightness] = hslStr.match(/\d+/g).map(Number);
const newLightness = Math.max(
0,
Math.min(100, lightness + parseFloat(delta))
);
return `hsl(${hue}, ${saturation}%, ${newLightness}%)`;
};
```
```js
changeLightness(10, 'hsl(330, 50%, 50%)'); // 'hsl(330, 50%, 60%)'
changeLightness(-10, 'hsl(330, 50%, 50%)'); // 'hsl(330, 50%, 40%)'
```

View File

@ -0,0 +1,36 @@
---
title: Check property
type: snippet
language: javascript
tags: [function,object]
cover: white-tablet-2
dateModified: 2020-11-01T20:50:57+02:00
---
Creates a function that will invoke a predicate function for the specified property on a given object.
- Return a curried function, that will invoke `predicate` for the specified `prop` on `obj` and return a boolean.
```js
const checkProp = (predicate, prop) => obj => !!predicate(obj[prop]);
```
```js
const lengthIs4 = checkProp(l => l === 4, 'length');
lengthIs4([]); // false
lengthIs4([1, 2, 3, 4]); // true
lengthIs4(new Set([1, 2, 3, 4])); // false (Set uses Size, not length)
const session = { user: {} };
const validUserSession = checkProp(u => u.active && !u.disabled, 'user');
validUserSession(session); // false
session.user.active = true;
validUserSession(session); // true
const noLength = checkProp(l => l === undefined, 'length');
noLength([]); // false
noLength({}); // true
noLength(new Set()); // true
```

View File

@ -0,0 +1,29 @@
---
title: Split array into n chunks
type: snippet
language: javascript
tags: [array]
author: chalarangelo
cover: dark-leaves-2
dateModified: 2020-11-03T21:46:13+02:00
---
Chunks an array into `n` smaller arrays.
- Use `Math.ceil()` and `Array.prototype.length` to get the size of each chunk.
- Use `Array.from()` to create a new array of size `n`.
- Use `Array.prototype.slice()` to map each element of the new array to a chunk the length of `size`.
- If the original array can't be split evenly, the final chunk will contain the remaining elements.
```js
const chunkIntoN = (arr, n) => {
const size = Math.ceil(arr.length / n);
return Array.from({ length: n }, (v, i) =>
arr.slice(i * size, i * size + size)
);
}
```
```js
chunkIntoN([1, 2, 3, 4, 5, 6, 7], 4); // [[1, 2], [3, 4], [5, 6], [7]]
```

25
snippets/js/s/chunk.md Normal file
View File

@ -0,0 +1,25 @@
---
title: Split into chunks
type: snippet
language: javascript
tags: [array]
cover: filter-coffee-pot
dateModified: 2020-11-03T21:35:12+02:00
---
Chunks an array into smaller arrays of a specified size.
- Use `Array.from()` to create a new array, that fits the number of chunks that will be produced.
- Use `Array.prototype.slice()` to map each element of the new array to a chunk the length of `size`.
- If the original array can't be split evenly, the final chunk will contain the remaining elements.
```js
const chunk = (arr, size) =>
Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
arr.slice(i * size, i * size + size)
);
```
```js
chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]]
```

34
snippets/js/s/chunkify.md Normal file
View File

@ -0,0 +1,34 @@
---
title: Chunk iterable
type: snippet
language: javascript
tags: [function,generator,array]
author: chalarangelo
cover: cave-view
dateModified: 2021-03-16T22:50:40+02:00
---
Chunks an iterable into smaller arrays of a specified size.
- Use a `for...of` loop over the given iterable, using `Array.prototype.push()` to add each new value to the current `chunk`.
- Use `Array.prototype.length` to check if the current `chunk` is of the desired `size` and `yield` the value if it is.
- Finally, use `Array.prototype.length` to check the final `chunk` and `yield` it if it's non-empty.
```js
const chunkify = function* (itr, size) {
let chunk = [];
for (const v of itr) {
chunk.push(v);
if (chunk.length === size) {
yield chunk;
chunk = [];
}
}
if (chunk.length) yield chunk;
};
```
```js
const x = new Set([1, 2, 1, 3, 4, 1, 2, 5]);
[...chunkify(x, 2)]; // [[1, 2], [3, 4], [5]]
```

View File

@ -0,0 +1,23 @@
---
title: Clamp number
type: snippet
language: javascript
tags: [math]
cover: clay-pot-horizon
dateModified: 2020-10-22T20:23:47+03:00
---
Clamps `num` within the inclusive range specified by the boundary values `a` and `b`.
- If `num` falls within the range, return `num`.
- Otherwise, return the nearest number in the range.
```js
const clampNumber = (num, a, b) =>
Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b));
```
```js
clampNumber(2, 3, 5); // 3
clampNumber(1, -1, -5); // -1
```

View File

@ -0,0 +1,21 @@
---
title: Clone RegExp
type: snippet
language: javascript
tags: [type]
cover: tomatoes
dateModified: 2020-10-22T20:23:47+03:00
---
Clones a regular expression.
- Use the `RegExp` constructor, `RegExp.prototype.source` and `RegExp.prototype.flags` to clone the given regular expression.
```js
const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags);
```
```js
const regExp = /lorem ipsum/gi;
const regExp2 = cloneRegExp(regExp); // regExp !== regExp2
```

23
snippets/js/s/closest.md Normal file
View File

@ -0,0 +1,23 @@
---
title: Closest numeric match
type: snippet
language: javascript
tags: [math]
author: chalarangelo
cover: sparkles
dateModified: 2022-03-30T05:00:00-04:00
---
Finds the closest number from an array.
- Use `Array.prototype.reduce()` to scan all elements of the array.
- Use `Math.abs()` to compare each element's distance from the target value, storing the closest match.
```js
const closest = (arr, n) =>
arr.reduce((acc, num) => (Math.abs(num - n) < Math.abs(acc - n) ? num : acc));
```
```js
closest([6, 1, 3, 7, 9], 5); // 6
```

View File

@ -0,0 +1,23 @@
---
title: Argument coalescing factory
type: snippet
language: javascript
tags: [function,type]
cover: coffee-phone-tray
dateModified: 2020-10-22T20:23:47+03:00
---
Customizes a coalesce function that returns the first argument which is `true` based on the given validator.
- Use `Array.prototype.find()` to return the first argument that returns `true` from the provided argument validation function, `valid`.
```js
const coalesceFactory = valid => (...args) => args.find(valid);
```
```js
const customCoalesce = coalesceFactory(
v => ![null, undefined, '', NaN].includes(v)
);
customCoalesce(undefined, null, NaN, '', 'Waldo'); // 'Waldo'
```

20
snippets/js/s/coalesce.md Normal file
View File

@ -0,0 +1,20 @@
---
title: Argument coalescing
type: snippet
language: javascript
tags: [type]
cover: flower-portrait-1
dateModified: 2020-09-15T16:28:04+03:00
---
Returns the first defined, non-null argument.
- Use `Array.prototype.find()` and `Array.prototype.includes()` to find the first value that is not equal to `undefined` or `null`.
```js
const coalesce = (...args) => args.find(v => ![undefined, null].includes(v));
```
```js
coalesce(null, undefined, '', NaN, 'Waldo'); // ''
```

View File

@ -0,0 +1,24 @@
---
title: Convert function to variadic
type: snippet
language: javascript
tags: [function,array]
cover: polar-bear
dateModified: 2021-06-13T13:50:25+03:00
---
Changes a function that accepts an array into a variadic function.
- Given a function, return a closure that collects all inputs into an array-accepting function.
```js
const collectInto = fn => (...args) => fn(args);
```
```js
const Pall = collectInto(Promise.all.bind(Promise));
let p1 = Promise.resolve(1);
let p2 = Promise.resolve(2);
let p3 = new Promise(resolve => setTimeout(resolve, 2000, 3));
Pall(p1, p2, p3).then(console.log); // [1, 2, 3] (after about 2 seconds)
```

41
snippets/js/s/colorize.md Normal file
View File

@ -0,0 +1,41 @@
---
title: Colorize text
type: snippet
language: javascript
tags: [node,string]
cover: sea-view
dateModified: 2020-11-03T22:11:18+02:00
---
Adds special characters to text to print in color in the console (combined with `console.log()`).
- Use template literals and special characters to add the appropriate color code to the string output.
- For background colors, add a special character that resets the background color at the end of the string.
```js
const colorize = (...args) => ({
black: `\x1b[30m${args.join(' ')}`,
red: `\x1b[31m${args.join(' ')}`,
green: `\x1b[32m${args.join(' ')}`,
yellow: `\x1b[33m${args.join(' ')}`,
blue: `\x1b[34m${args.join(' ')}`,
magenta: `\x1b[35m${args.join(' ')}`,
cyan: `\x1b[36m${args.join(' ')}`,
white: `\x1b[37m${args.join(' ')}`,
bgBlack: `\x1b[40m${args.join(' ')}\x1b[0m`,
bgRed: `\x1b[41m${args.join(' ')}\x1b[0m`,
bgGreen: `\x1b[42m${args.join(' ')}\x1b[0m`,
bgYellow: `\x1b[43m${args.join(' ')}\x1b[0m`,
bgBlue: `\x1b[44m${args.join(' ')}\x1b[0m`,
bgMagenta: `\x1b[45m${args.join(' ')}\x1b[0m`,
bgCyan: `\x1b[46m${args.join(' ')}\x1b[0m`,
bgWhite: `\x1b[47m${args.join(' ')}\x1b[0m`
});
```
```js
console.log(colorize('foo').red); // 'foo' (red letters)
console.log(colorize('foo', 'bar').bgBlue); // 'foo bar' (blue background)
console.log(colorize(colorize('foo').yellow, colorize('foo').green).bgWhite);
// 'foo bar' (first word in yellow letters, second word in green letters, white background for both)
```

45
snippets/js/s/combine.md Normal file
View File

@ -0,0 +1,45 @@
---
title: Combine object arrays
type: snippet
language: javascript
tags: [array,object]
author: chalarangelo
cover: digital-nomad-6
dateModified: 2020-10-08T02:22:39+03:00
---
Combines two arrays of objects, using the specified key to match objects.
- Use `Array.prototype.reduce()` with an object accumulator to combine all objects in both arrays based on the given `prop`.
- Use `Object.values()` to convert the resulting object to an array and return it.
```js
const combine = (a, b, prop) =>
Object.values(
[...a, ...b].reduce((acc, v) => {
if (v[prop])
acc[v[prop]] = acc[v[prop]]
? { ...acc[v[prop]], ...v }
: { ...v };
return acc;
}, {})
);
```
```js
const x = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Maria' }
];
const y = [
{ id: 1, age: 28 },
{ id: 3, age: 26 },
{ age: 3}
];
combine(x, y, 'id');
// [
// { id: 1, name: 'John', age: 28 },
// { id: 2, name: 'Maria' },
// { id: 3, age: 26 }
// ]
```

View File

@ -0,0 +1,24 @@
---
title: Common keys
type: snippet
language: javascript
tags: [object]
author: chalarangelo
cover: symmetry-cloudy-mountain
dateModified: 2022-04-23T05:00:00-04:00
---
Finds the common keys between two objects.
- Use `Object.keys()` to get the keys of the first object.
- Use `Object.prototype.hasOwnProperty()` to check if the second object has a key that's in the first object.
- Use `Array.prototype.filter()` to filter out keys that aren't in both objects.
```js
const commonKeys = (obj1, obj2) =>
Object.keys(obj1).filter(key => obj2.hasOwnProperty(key));
```
```js
commonKeys({ a: 1, b: 2 }, { a: 2, c: 1 }); // ['a']
```

View File

@ -0,0 +1,22 @@
---
title: Compact and join array
type: snippet
language: javascript
tags: [array]
author: chalarangelo
cover: racoon
dateModified: 2022-04-08T05:00:00-04:00
---
Removes falsy values from an array and combines the remaining values into a string.
- Use `Array.prototype.filter()` to filter out falsy values (`false`, `null`, `0`, `""`, `undefined`, and `NaN`).
- Use `Array.prototype.join()` to join the remaining values into a string.
```js
const compactJoin = (arr, delim = ',') => arr.filter(Boolean).join(delim);
```
```js
compactJoin(['a', '', 'b', 'c']); // 'a,b,c'
```

View File

@ -0,0 +1,47 @@
---
title: Compact object
type: snippet
language: javascript
tags: [object,array,recursion]
cover: shapes
dateModified: 2020-11-27T13:57:41+02:00
---
Deeply removes all falsy values from an object or array.
- Use recursion.
- Initialize the iterable data, using `Array.isArray()`, `Array.prototype.filter()` and `Boolean` for arrays in order to avoid sparse arrays.
- Use `Object.keys()` and `Array.prototype.reduce()` to iterate over each key with an appropriate initial value.
- Use `Boolean` to determine the truthiness of each key's value and add it to the accumulator if it's truthy.
- Use `typeof` to determine if a given value is an `object` and call the function again to deeply compact it.
```js
const compactObject = val => {
const data = Array.isArray(val) ? val.filter(Boolean) : val;
return Object.keys(data).reduce(
(acc, key) => {
const value = data[key];
if (Boolean(value))
acc[key] = typeof value === 'object' ? compactObject(value) : value;
return acc;
},
Array.isArray(val) ? [] : {}
);
};
```
```js
const obj = {
a: null,
b: false,
c: true,
d: 0,
e: 1,
f: '',
g: 'a',
h: [null, false, '', true, 1, 'a'],
i: { j: 0, k: false, l: 'a' }
};
compactObject(obj);
// { c: true, e: 1, g: 'a', h: [ true, 1, 'a' ], i: { l: 'a' } }
```

View File

@ -0,0 +1,21 @@
---
title: Compact whitespaces
type: snippet
language: javascript
tags: [string,regexp]
cover: travel-mug-1
dateModified: 2020-10-18T23:04:45+03:00
---
Compacts whitespaces in a string.
- Use `String.prototype.replace()` with a regular expression to replace all occurrences of 2 or more whitespace characters with a single space.
```js
const compactWhitespace = str => str.replace(/\s{2,}/g, ' ');
```
```js
compactWhitespace('Lorem Ipsum'); // 'Lorem Ipsum'
compactWhitespace('Lorem \n Ipsum'); // 'Lorem Ipsum'
```

21
snippets/js/s/compact.md Normal file
View File

@ -0,0 +1,21 @@
---
title: Compact array
type: snippet
language: javascript
tags: [array]
cover: basket-paper
dateModified: 2020-10-22T20:23:47+03:00
---
Removes falsy values from an array.
- Use `Array.prototype.filter()` to filter out falsy values (`false`, `null`, `0`, `""`, `undefined`, and `NaN`).
```js
const compact = arr => arr.filter(Boolean);
```
```js
compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]);
// [ 1, 2, 3, 'a', 's', 34 ]
```

View File

@ -0,0 +1,23 @@
---
title: Logical complement
type: snippet
language: javascript
tags: [function,logic]
cover: flower-portrait-10
dateModified: 2020-09-15T16:28:04+03:00
---
Returns a function that is the logical complement of the given function, `fn`.
- Use the logical not (`!`) operator on the result of calling `fn` with any supplied `args`.
```js
const complement = fn => (...args) => !fn(...args);
```
```js
const isEven = num => num % 2 === 0;
const isOdd = complement(isEven);
isOdd(2); // false
isOdd(3); // true
```

View File

@ -0,0 +1,25 @@
---
title: Reverse compose functions
type: snippet
language: javascript
tags: [function]
cover: rocky-beach
dateModified: 2020-10-22T20:23:47+03:00
---
Performs left-to-right function composition.
- Use `Array.prototype.reduce()` to perform left-to-right function composition.
- The first (leftmost) function can accept one or more arguments; the remaining functions must be unary.
```js
const composeRight = (...fns) =>
fns.reduce((f, g) => (...args) => g(f(...args)));
```
```js
const add = (x, y) => x + y;
const square = x => x * x;
const addAndSquare = composeRight(add, square);
addAndSquare(1, 2); // 9
```

28
snippets/js/s/compose.md Normal file
View File

@ -0,0 +1,28 @@
---
title: Compose functions
type: snippet
language: javascript
tags: [function]
cover: digital-nomad-16
dateModified: 2020-10-22T20:23:47+03:00
---
Performs right-to-left function composition.
- Use `Array.prototype.reduce()` to perform right-to-left function composition.
- The last (rightmost) function can accept one or more arguments; the remaining functions must be unary.
```js
const compose = (...fns) =>
fns.reduce((f, g) => (...args) => f(g(...args)));
```
```js
const add5 = x => x + 5;
const multiply = (x, y) => x * y;
const multiplyAndAdd5 = compose(
add5,
multiply
);
multiplyAndAdd5(5, 2); // 15
```

View File

@ -0,0 +1,22 @@
---
title: Check if string contains whitespace
type: snippet
language: javascript
tags: [string,regexp]
author: chalarangelo
cover: bag-waiting
dateModified: 2020-10-18T23:04:45+03:00
---
Checks if the given string contains any whitespace characters.
- Use `RegExp.prototype.test()` with an appropriate regular expression to check if the given string contains any whitespace characters.
```js
const containsWhitespace = str => /\s/.test(str);
```
```js
containsWhitespace('lorem'); // false
containsWhitespace('lorem ipsum'); // true
```

27
snippets/js/s/converge.md Normal file
View File

@ -0,0 +1,27 @@
---
title: Converge branching functions
type: snippet
language: javascript
tags: [function]
excerpt: Converges a list of branching functions into a single function and returns the result.
cover: cherry-trees
dateModified: 2021-01-08T00:23:44+02:00
---
Accepts a converging function and a list of branching functions and returns a function that applies each branching function to the arguments and the results of the branching functions are passed as arguments to the converging function.
- Use `Array.prototype.map()` and `Function.prototype.apply()` to apply each function to the given arguments.
- Use the spread operator (`...`) to call `converger` with the results of all other functions.
```js
const converge = (converger, fns) => (...args) =>
converger(...fns.map(fn => fn.apply(null, args)));
```
```js
const average = converge((a, b) => a / b, [
arr => arr.reduce((a, v) => a + v, 0),
arr => arr.length
]);
average([1, 2, 3, 4, 5, 6, 7]); // 4
```

View File

@ -0,0 +1,24 @@
---
title: Copy sign to number
type: snippet
language: javascript
tags: [math]
cover: keyboard-tea
dateModified: 2020-10-07T23:52:57+03:00
---
Returns the absolute value of the first number, but the sign of the second.
- Use `Math.sign()` to check if the two numbers have the same sign.
- Return `x` if they do, `-x` otherwise.
```js
const copySign = (x, y) => Math.sign(x) === Math.sign(y) ? x : -x;
```
```js
copySign(2, 3); // 2
copySign(2, -3); // -2
copySign(-2, 3); // 2
copySign(-2, -3); // -2
```

View File

@ -0,0 +1,28 @@
---
title: Copy to clipboard async
type: snippet
language: javascript
tags: [browser,string,promise]
cover: typing
dateModified: 2022-01-11T05:00:00-04:00
---
Copies a string to the clipboard, returning a promise that resolves when the clipboard's contents have been updated.
- Check if the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) is available. Use an `if` statement to ensure `Navigator`, `Navigator.clipboard` and `Navigator.clipboard.writeText` are truthy.
- Use `Clipboard.writeText()` to write the given value, `str`, to the clipboard.
- Return the result of `Clipboard.writeText()`, which is a promise that resolves when the clipboard's contents have been updated.
- In case that the Clipboard API is not available, use `Promise.reject()` to reject with an appropriate message.
- **Note:** If you need to support older browsers, you might want to use `Document.execCommand()` instead. You can find out more about it in the [copyToClipboard snippet](/js/s/copy-to-clipboard).
```js
const copyToClipboardAsync = str => {
if (navigator && navigator.clipboard && navigator.clipboard.writeText)
return navigator.clipboard.writeText(str);
return Promise.reject('The Clipboard API is not available.');
};
```
```js
copyToClipboardAsync('Lorem ipsum'); // 'Lorem ipsum' copied to clipboard.
```

View File

@ -0,0 +1,44 @@
---
title: Copy to clipboard
type: snippet
language: javascript
tags: [browser,string,event]
cover: typing
dateModified: 2022-01-11T09:32:04+02:00
---
Copies a string to the clipboard.
Only works as a result of user action (i.e. inside a `click` event listener).
- Create a new `<textarea>` element, fill it with the supplied data and add it to the HTML document.
- Use `Selection.getRangeAt()`to store the selected range (if any).
- Use `Document.execCommand()` to copy to the clipboard.
- Remove the `<textarea>` element from the HTML document.
- Finally, use `Selection.addRange()` to recover the original selected range (if any).
- **Note:** You can use the asynchronous [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API) in most current browsers. You can find out more about it in the [copyToClipboardAsync snippet](/js/s/copy-to-clipboard-async).
```js
const copyToClipboard = str => {
const el = document.createElement('textarea');
el.value = str;
el.setAttribute('readonly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);
const selected =
document.getSelection().rangeCount > 0
? document.getSelection().getRangeAt(0)
: false;
el.select();
document.execCommand('copy');
document.body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
};
```
```js
copyToClipboard('Lorem ipsum'); // 'Lorem ipsum' copied to clipboard.
```

28
snippets/js/s/count-by.md Normal file
View File

@ -0,0 +1,28 @@
---
title: Count grouped elements
type: snippet
language: javascript
tags: [array,object]
cover: tools
dateModified: 2020-11-03T22:11:18+02:00
---
Groups the elements of an array based on the given function and returns the count of elements in each group.
- Use `Array.prototype.map()` to map the values of an array to a function or property name.
- Use `Array.prototype.reduce()` to create an object, where the keys are produced from the mapped results.
```js
const countBy = (arr, fn) =>
arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => {
acc[val] = (acc[val] || 0) + 1;
return acc;
}, {});
```
```js
countBy([6.1, 4.2, 6.3], Math.floor); // {4: 1, 6: 2}
countBy(['one', 'two', 'three'], 'length'); // {3: 2, 5: 1}
countBy([{ count: 5 }, { count: 10 }, { count: 5 }], x => x.count)
// {5: 2, 10: 1}
```

View File

@ -0,0 +1,21 @@
---
title: Count occurrences
type: snippet
language: javascript
tags: [array]
cover: dark-leaves-4
dateModified: 2020-10-18T23:04:45+03:00
---
Counts the occurrences of a value in an array.
- Use `Array.prototype.reduce()` to increment a counter each time the specific value is encountered inside the array.
```js
const countOccurrences = (arr, val) =>
arr.reduce((a, v) => (v === val ? a + 1 : a), 0);
```
```js
countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3
```

View File

@ -0,0 +1,32 @@
---
title: Count substrings of string
type: snippet
language: javascript
tags: [string,algorithm]
author: chalarangelo
cover: obelisk
dateModified: 2021-01-08T00:23:44+02:00
---
Counts the occurrences of a substring in a given string.
- Use `Array.prototype.indexOf()` to look for `searchValue` in `str`.
- Increment a counter if the value is found and update the index, `i`.
- Use a `while` loop that will return as soon as the value returned from `Array.prototype.indexOf()` is `-1`.
```js
const countSubstrings = (str, searchValue) => {
let count = 0,
i = 0;
while (true) {
const r = str.indexOf(searchValue, i);
if (r !== -1) [count, i] = [count + 1, r + 1];
else return count;
}
};
```
```js
countSubstrings('tiktok tok tok tik tok tik', 'tik'); // 3
countSubstrings('tutut tut tut', 'tut'); // 4
```

View File

@ -0,0 +1,31 @@
---
title: Count weekdays between two dates
type: snippet
language: javascript
tags: [date]
cover: organizer
dateModified: 2020-10-20T11:21:07+03:00
---
Counts the weekdays between two dates.
- Use `Array.from()` to construct an array with `length` equal to the number of days between `startDate` and `endDate`.
- Use `Array.prototype.reduce()` to iterate over the array, checking if each date is a weekday and incrementing `count`.
- Update `startDate` with the next day each loop using `Date.prototype.getDate()` and `Date.prototype.setDate()` to advance it by one day.
- **NOTE:** Does not take official holidays into account.
```js
const countWeekDaysBetween = (startDate, endDate) =>
Array
.from({ length: (endDate - startDate) / (1000 * 3600 * 24) })
.reduce(count => {
if (startDate.getDay() % 6 !== 0) count++;
startDate = new Date(startDate.setDate(startDate.getDate() + 1));
return count;
}, 0);
```
```js
countWeekDaysBetween(new Date('Oct 05, 2020'), new Date('Oct 06, 2020')); // 1
countWeekDaysBetween(new Date('Oct 05, 2020'), new Date('Oct 14, 2020')); // 7
```

35
snippets/js/s/counter.md Normal file
View File

@ -0,0 +1,35 @@
---
title: Counter
type: snippet
language: javascript
tags: [browser]
cover: touch-flower
dateModified: 2020-11-01T20:50:57+02:00
---
Creates a counter with the specified range, step and duration for the specified selector.
- Check if `step` has the proper sign and change it accordingly.
- Use `setInterval()` in combination with `Math.abs()` and `Math.floor()` to calculate the time between each new text draw.
- Use `Document.querySelector()`, `Element.innerHTML` to update the value of the selected element.
- Omit the fourth argument, `step`, to use a default step of `1`.
- Omit the fifth argument, `duration`, to use a default duration of `2000`ms.
```js
const counter = (selector, start, end, step = 1, duration = 2000) => {
let current = start,
_step = (end - start) * step < 0 ? -step : step,
timer = setInterval(() => {
current += _step;
document.querySelector(selector).innerHTML = current;
if (current >= end) document.querySelector(selector).innerHTML = end;
if (current >= end) clearInterval(timer);
}, Math.abs(Math.floor(duration / (end - start))));
return timer;
};
```
```js
counter('#my-id', 1, 1000, 5, 2000);
// Creates a 2-second timer for the element with id="my-id"
```

View File

@ -0,0 +1,24 @@
---
title: Create directory if not exists
type: snippet
language: javascript
tags: [node]
cover: sunrise-over-city
dateModified: 2020-10-22T20:23:47+03:00
---
Creates a directory, if it does not exist.
- Use `fs.existsSync()` to check if the directory exists, `fs.mkdirSync()` to create it.
```js
const fs = require('fs');
const createDirIfNotExists = dir =>
!fs.existsSync(dir) ? fs.mkdirSync(dir) : undefined;
```
```js
createDirIfNotExists('test');
// creates the directory 'test', if it doesn't exist
```

View File

@ -0,0 +1,33 @@
---
title: Create HTML element
type: snippet
language: javascript
tags: [browser]
cover: flower-portrait-4
excerpt: Creates an element from a string without appending it to the document.
dateModified: 2020-10-19T18:51:03+03:00
---
Creates an element from a string (without appending it to the document).
If the given string contains multiple elements, only the first one will be returned.
- Use `Document.createElement()` to create a new element.
- Use `Element.innerHTML` to set its inner HTML to the string supplied as the argument.
- Use `Element.firstElementChild` to return the element version of the string.
```js
const createElement = str => {
const el = document.createElement('div');
el.innerHTML = str;
return el.firstElementChild;
};
```
```js
const el = createElement(
`<div class="container">
<p>Hello!</p>
</div>`
);
console.log(el.className); // 'container'
```

View File

@ -0,0 +1,54 @@
---
title: Create event hub
type: snippet
language: javascript
tags: [browser,event]
cover: city-view
excerpt: Creates a pub/sub event hub with emit, on, and off methods.
dateModified: 2020-09-15T16:28:04+03:00
---
Creates a pub/sub ([publishsubscribe](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern)) event hub with `emit`, `on`, and `off` methods.
- Use `Object.create()` with an argument of `null` to create an empty `hub` object that does not inherit properties from `Object.prototype`.
- For `emit`, resolve the array of handlers based on the `event` argument and then run each one with `Array.prototype.forEach()` by passing in the data as an argument.
- For `on`, create an array for the event if it does not yet exist, then use `Array.prototype.push()` to add the handler
- to the array.
- For `off`, use `Array.prototype.findIndex()` to find the index of the handler in the event array and remove it using `Array.prototype.splice()`.
```js
const createEventHub = () => ({
hub: Object.create(null),
emit(event, data) {
(this.hub[event] || []).forEach(handler => handler(data));
},
on(event, handler) {
if (!this.hub[event]) this.hub[event] = [];
this.hub[event].push(handler);
},
off(event, handler) {
const i = (this.hub[event] || []).findIndex(h => h === handler);
if (i > -1) this.hub[event].splice(i, 1);
if (this.hub[event].length === 0) delete this.hub[event];
}
});
```
```js
const handler = data => console.log(data);
const hub = createEventHub();
let increment = 0;
// Subscribe: listen for different types of events
hub.on('message', handler);
hub.on('message', () => console.log('Message event fired'));
hub.on('increment', () => increment++);
// Publish: emit events to invoke all handlers subscribed to them, passing the data to them as an argument
hub.emit('message', 'hello world'); // logs 'hello world' and 'Message event fired'
hub.emit('message', { hello: 'world' }); // logs the object and 'Message event fired'
hub.emit('increment'); // `increment` variable is now 1
// Unsubscribe: stop a specific handler from listening to the 'message' event
hub.off('message', handler);
```

View File

@ -0,0 +1,31 @@
---
title: CSV to array
type: snippet
language: javascript
tags: [string,array]
cover: keyboard-tea
dateModified: 2022-01-30T12:14:39+02:00
---
Converts a comma-separated values (CSV) string to a 2D array.
- Use `Array.prototype.indexOf()` to find the first newline character (`\n`).
- Use `Array.prototype.slice()` to remove the first row (title row) if `omitFirstRow` is `true`.
- Use `String.prototype.split()` to create a string for each row.
- Use `String.prototype.split()` to separate the values in each row, using the provided `delimiter`.
- Omit the second argument, `delimiter`, to use a default delimiter of `','`.
- Omit the third argument, `omitFirstRow`, to include the first row (title row) of the CSV string.
```js
const CSVToArray = (data, delimiter = ',', omitFirstRow = false) =>
data
.slice(omitFirstRow ? data.indexOf('\n') + 1 : 0)
.split('\n')
.map(v => v.split(delimiter));
```
```js
CSVToArray('a,b\nc,d'); // [['a', 'b'], ['c', 'd']];
CSVToArray('a;b\nc;d', ';'); // [['a', 'b'], ['c', 'd']];
CSVToArray('col1,col2\na,b\nc,d', ',', true); // [['a', 'b'], ['c', 'd']];
```

View File

@ -0,0 +1,41 @@
---
title: CSV to JSON
type: snippet
language: javascript
tags: [string,object]
cover: kettle-laptop
dateModified: 2022-01-30T12:14:39+02:00
---
Converts a comma-separated values (CSV) string to a 2D array of objects.
The first row of the string is used as the title row.
- Use `Array.prototype.indexOf()` to find the first newline character (`\n`).
- Use `Array.prototype.slice()` to remove the first row (title row) and `String.prototype.split()` to separate it into values, using the provided `delimiter`.
- Use `String.prototype.split()` to create a string for each row.
- Use `String.prototype.split()` to separate the values in each row, using the provided `delimiter`.
- Use `Array.prototype.reduce()` to create an object for each row's values, with the keys parsed from the title row.
- Omit the second argument, `delimiter`, to use a default delimiter of `,`.
```js
const CSVToJSON = (data, delimiter = ',') => {
const titles = data.slice(0, data.indexOf('\n')).split(delimiter);
return data
.slice(data.indexOf('\n') + 1)
.split('\n')
.map(v => {
const values = v.split(delimiter);
return titles.reduce(
(obj, title, index) => ((obj[title] = values[index]), obj),
{}
);
});
};
```
```js
CSVToJSON('col1,col2\na,b\nc,d');
// [{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}];
CSVToJSON('col1;col2\na;b\nc;d', ';');
// [{'col1': 'a', 'col2': 'b'}, {'col1': 'c', 'col2': 'd'}];
```

View File

@ -0,0 +1,20 @@
---
title: Current URL
type: snippet
language: javascript
tags: [browser]
cover: tropical-bike
dateModified: 2020-10-20T11:46:23+03:00
---
Returns the current URL.
- Use `Window.location.href` to get the current URL.
```js
const currentURL = () => window.location.href;
```
```js
currentURL(); // 'https://www.google.com/'
```

25
snippets/js/s/curry.md Normal file
View File

@ -0,0 +1,25 @@
---
title: Curry function
type: snippet
language: javascript
tags: [function,recursion]
cover: rocky-beach-2
dateModified: 2020-10-22T20:23:47+03:00
---
Curries a function.
- Use recursion.
- If the number of provided arguments (`args`) is sufficient, call the passed function `fn`.
- Otherwise, use `Function.prototype.bind()` to return a curried function `fn` 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 = (fn, arity = fn.length, ...args) =>
arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args);
```
```js
curry(Math.pow)(2)(10); // 1024
curry(Math.min, 3)(10)(50)(2); // 2
```

View File

@ -0,0 +1,32 @@
---
title: Cycle generator
type: snippet
language: javascript
tags: [function,generator]
author: chalarangelo
cover: secret-tree
dateModified: 2020-10-11T17:05:38+03:00
---
Creates a generator, looping over the given array indefinitely.
- Use a non-terminating `while` loop, that will `yield` a value every time `Generator.prototype.next()` is called.
- Use the module operator (`%`) with `Array.prototype.length` to get the next value's index and increment the counter after each `yield` statement.
```js
const cycleGenerator = function* (arr) {
let i = 0;
while (true) {
yield arr[i % arr.length];
i++;
}
};
```
```js
const binaryCycle = cycleGenerator([0, 1]);
binaryCycle.next(); // { value: 0, done: false }
binaryCycle.next(); // { value: 1, done: false }
binaryCycle.next(); // { value: 0, done: false }
binaryCycle.next(); // { value: 1, done: false }
```

View File

@ -0,0 +1,29 @@
---
title: Date range generator
type: snippet
language: javascript
tags: [date,function,generator]
cover: portal-timelapse
dateModified: 2021-06-21T05:00:00-04:00
---
Creates a generator, that generates all dates in the given range using the given step.
- Use a `while` loop to iterate from `start` to `end`, using `yield` to return each date in the range, using the `Date` constructor.
- Use `Date.prototype.getDate()` and `Date.prototype.setDate()` to increment by `step` days after returning each subsequent value.
- Omit the third argument, `step`, to use a default value of `1`.
```js
const dateRangeGenerator = function* (start, end, step = 1) {
let d = start;
while (d < end) {
yield new Date(d);
d.setDate(d.getDate() + step);
}
};
```
```js
[...dateRangeGenerator(new Date('2021-06-01'), new Date('2021-06-04'))];
// [ 2021-06-01, 2021-06-02, 2021-06-03 ]
```

23
snippets/js/s/day-name.md Normal file
View File

@ -0,0 +1,23 @@
---
title: Day name
type: snippet
language: javascript
tags: [date]
cover: interior
dateModified: 2020-11-01T20:50:57+02:00
---
Gets the name of the weekday from a `Date` object.
- Use `Date.prototype.toLocaleDateString()` with the `{ weekday: 'long' }` option to retrieve the weekday.
- Use the optional second argument to get a language-specific name or omit it to use the default locale.
```js
const dayName = (date, locale) =>
date.toLocaleDateString(locale, { weekday: 'long' });
```
```js
dayName(new Date()); // 'Saturday'
dayName(new Date('09/23/2020'), 'de-DE'); // 'Samstag'
```

View File

@ -0,0 +1,23 @@
---
title: Day of year
type: snippet
language: javascript
tags: [date]
cover: interior-3
dateModified: 2020-10-19T18:51:03+03:00
---
Gets the day of the year (number in the range 1-366) from a `Date` object.
- Use the `Date` constructor and `Date.prototype.getFullYear()` to get the first day of the year as a `Date` object.
- Subtract the first day of the year from `date` and divide with the milliseconds in each day to get the result.
- Use `Math.floor()` to appropriately round the resulting day count to an integer.
```js
const dayOfYear = date =>
Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);
```
```js
dayOfYear(new Date()); // 272
```

26
snippets/js/s/days-ago.md Normal file
View File

@ -0,0 +1,26 @@
---
title: Days ago
type: snippet
language: javascript
tags: [date]
cover: sunrise-over-city
dateModified: 2022-01-30T11:48:07+03:00
---
Calculates the date of `n` days ago from today as a string representation.
- Use the `Date` constructor to get the current date.
- Use `Math.abs()` and `Date.prototype.getDate()` to update the date accordingly and set to the result using `Date.prototype.setDate()`.
- Use `Date.prototype.toISOString()` to return a string in `yyyy-mm-dd` format.
```js
const daysAgo = n => {
let d = new Date();
d.setDate(d.getDate() - Math.abs(n));
return d.toISOString().split('T')[0];
};
```
```js
daysAgo(20); // 2020-09-16 (if current date is 2020-10-06)
```

View File

@ -0,0 +1,26 @@
---
title: Days from now
type: snippet
language: javascript
tags: [date]
cover: tent-stars
dateModified: 2022-01-30T11:48:07+03:00
---
Calculates the date of `n` days from today as a string representation.
- Use the `Date` constructor to get the current date.
- Use `Math.abs()` and `Date.prototype.getDate()` to update the date accordingly and set to the result using `Date.prototype.setDate()`.
- Use `Date.prototype.toISOString()` to return a string in `yyyy-mm-dd` format.
```js
const daysFromNow = n => {
let d = new Date();
d.setDate(d.getDate() + Math.abs(n));
return d.toISOString().split('T')[0];
};
```
```js
daysFromNow(5); // 2020-10-13 (if current date is 2020-10-08)
```

View File

@ -0,0 +1,23 @@
---
title: Number of days in month
type: snippet
language: javascript
tags: [date]
cover: laptop-plants-2
dateModified: 2021-06-13T05:00:00-04:00
---
Gets the number of days in the given `month` of the specified `year`.
- Use the `Date` constructor to create a date from the given `year` and `month`.
- Set the days parameter to `0` to get the last day of the previous month, as months are zero-indexed.
- Use `Date.prototype.getDate()` to return the number of days in the given `month`.
```js
const daysInMonth = (year, month) => new Date(year, month, 0).getDate();
```
```js
daysInMonth(2020, 12)); // 31
daysInMonth(2024, 2)); // 29
```

View File

@ -0,0 +1,53 @@
---
title: Debounce promise
type: snippet
language: javascript
tags: [function,promise]
excerpt: Creates a debounced function that returns a promise.
cover: ice
dateModified: 2020-10-19T18:51:03+03:00
---
Creates a debounced function that returns a promise, but delays invoking the provided function until at least `ms` milliseconds have elapsed since the last time it was invoked.
All promises returned during this time will return the same data.
- Each time the debounced function is invoked, clear the current pending timeout with `clearTimeout()` and use `setTimeout()` to create a new timeout that delays invoking the function until at least `ms` milliseconds has elapsed.
- Use `Function.prototype.apply()` to apply the `this` context to the function and provide the necessary arguments.
- Create a new `Promise` and add its `resolve` and `reject` callbacks to the `pending` promises stack.
- When `setTimeout()` is called, copy the current stack (as it can change between the provided function call and its resolution), clear it and call the provided function.
- When the provided function resolves/rejects, resolve/reject all promises in the stack (copied when the function was called) with the returned data.
- Omit the second argument, `ms`, to set the timeout at a default of `0` ms.
```js
const debouncePromise = (fn, ms = 0) => {
let timeoutId;
const pending = [];
return (...args) =>
new Promise((res, rej) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
const currentPending = [...pending];
pending.length = 0;
Promise.resolve(fn.apply(this, args)).then(
data => {
currentPending.forEach(({ resolve }) => resolve(data));
},
error => {
currentPending.forEach(({ reject }) => reject(error));
}
);
}, ms);
pending.push({ resolve: res, reject: rej });
});
};
```
```js
const fn = arg => new Promise(resolve => {
setTimeout(resolve, 1000, ['resolved', arg]);
});
const debounced = debouncePromise(fn, 200);
debounced('foo').then(console.log);
debounced('bar').then(console.log);
// Will log ['resolved', 'bar'] both times
```

35
snippets/js/s/debounce.md Normal file
View File

@ -0,0 +1,35 @@
---
title: Debounce function
type: snippet
language: javascript
tags: [function]
cover: solitude-beach
excerpt: Creates a debounced function that waits `ms` milliseconds before invoking the provided function again.
dateModified: 2021-10-13T19:29:39+02:00
---
Creates a debounced function that delays invoking the provided function until at least `ms` milliseconds have elapsed since its last invocation.
- Each time the debounced function is invoked, clear the current pending timeout with `clearTimeout()`. Use `setTimeout()` to create a new timeout that delays invoking the function until at least `ms` milliseconds have elapsed.
- Use `Function.prototype.apply()` to apply the `this` context to the function and provide the necessary arguments.
- Omit the second argument, `ms`, to set the timeout at a default of `0` ms.
```js
const debounce = (fn, ms = 0) => {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), ms);
};
};
```
```js
window.addEventListener(
'resize',
debounce(() => {
console.log(window.innerWidth);
console.log(window.innerHeight);
}, 250)
); // Will log the window dimensions at most every 250ms
```

View File

@ -0,0 +1,24 @@
---
title: Decapitalize string
type: snippet
language: javascript
tags: [string]
cover: forest-balcony
dateModified: 2020-11-01T20:50:57+02:00
---
Decapitalizes the first letter of a string.
- Use array destructuring and `String.prototype.toLowerCase()` to decapitalize first letter, `...rest` to get array of characters after first letter and then `Array.prototype.join()` to make it a string again.
- Omit the `upperRest` argument to keep the rest of the string intact, or set it to `true` to convert to uppercase.
```js
const decapitalize = ([first, ...rest], upperRest = false) =>
first.toLowerCase() +
(upperRest ? rest.join('').toUpperCase() : rest.join(''));
```
```js
decapitalize('FooBar'); // 'fooBar'
decapitalize('FooBar', true); // 'fOOBAR'
```

View File

@ -0,0 +1,39 @@
---
title: Deep clone object
type: snippet
language: javascript
tags: [object,recursion]
cover: neon-desk-2
dateModified: 2020-10-22T20:23:47+03:00
---
Creates a deep clone of an object.
Clones primitives, arrays and objects, excluding class instances.
- Use recursion.
- Check if the passed object is `null` and, if so, return `null`.
- Use `Object.assign()` and an empty object (`{}`) to create a shallow clone of the original.
- Use `Object.keys()` and `Array.prototype.forEach()` to determine which key-value pairs need to be deep cloned.
- If the object is an `Array`, set the `clone`'s `length` to that of the original and use `Array.from()` to create a clone.
```js
const deepClone = obj => {
if (obj === null) return null;
let clone = Object.assign({}, obj);
Object.keys(clone).forEach(
key =>
(clone[key] =
typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
);
if (Array.isArray(obj)) {
clone.length = obj.length;
return Array.from(clone);
}
return clone;
};
```
```js
const a = { foo: 'bar', obj: { a: 1, b: 2 } };
const b = deepClone(a); // a !== b, a.obj !== b.obj
```

View File

@ -0,0 +1,23 @@
---
title: Deep flatten array
type: snippet
language: javascript
tags: [array,recursion]
cover: digital-nomad-4
dateModified: 2020-10-22T20:23:47+03:00
---
Deep flattens an array.
- Use recursion.
- Use `Array.prototype.concat()` with an empty array (`[]`) and the spread operator (`...`) to flatten an array.
- Recursively flatten each element that is an array.
```js
const deepFlatten = arr =>
[].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));
```
```js
deepFlatten([1, [2], [[3], 4], 5]); // [1, 2, 3, 4, 5]
```

Some files were not shown because too many files have changed in this diff Show More