diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..940c318b4 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,20 @@ + + + + +## Description + +**Resolves** #(issue number) + +## Types of changes +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) + +## Checklist: + +- [ ] My code follows the code style of this project. +- [ ] My change requires a change to the documentation. +- [ ] I have updated the documentation accordingly. +- [ ] I have checked that there isn't any PR doing the same +- [ ] I have read the **CONTRIBUTING** document. diff --git a/README.md b/README.md index 3ba0a832b..bce4069d1 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ - Use Ctrl + F or command + F to search for a snippet. - Contributions welcome, please read the [contribution guide](CONTRIBUTING.md). - Snippets are written in ES6, use the [Babel transpiler](https://babeljs.io/) to ensure backwards-compatibility. +- You can import these snippets into Alfred 3, using [this file](https://github.com/lslvxy/30-seconds-of-code-alfredsnippets). ## Table of Contents @@ -17,8 +18,10 @@ * [`countOccurrences`](#countoccurrences) * [`deepFlatten`](#deepflatten) * [`difference`](#difference) +* [`differenceWith`](#differencewith) * [`distinctValuesOfArray`](#distinctvaluesofarray) * [`dropElements`](#dropelements) +* [`dropRight`](#dropright) * [`everyNth`](#everynth) * [`filterNonUnique`](#filternonunique) * [`flatten`](#flatten) @@ -34,6 +37,8 @@ * [`nthElement`](#nthelement) * [`pick`](#pick) * [`pull`](#pull) +* [`pullAtIndex`](#pullatindex) +* [`pullAtValue`](#pullatvalue) * [`remove`](#remove) * [`sample`](#sample) * [`shuffle`](#shuffle) @@ -103,6 +108,7 @@ * [`cleanObj`](#cleanobj) * [`objectFromPairs`](#objectfrompairs) * [`objectToPairs`](#objecttopairs) +* [`select`](#select) * [`shallowClone`](#shallowclone) * [`truthCheckCollection`](#truthcheckcollection) @@ -235,6 +241,19 @@ const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has [⬆ back to top](#table-of-contents) +### differenceWith + +Filters out all values from an array for which the comparator function does not return `true`. + +Use `Array.filter()` and `Array.find()` to find the appropriate values. + +```js +const differenceWith = (arr, val, comp) => arr.filter(a => !val.find(b => comp(a, b))) +// differenceWith([1, 1.2, 1.5, 3], [1.9, 3], (a,b) => Math.round(a) == Math.round(b)) -> [1, 1.2] +``` + +[⬆ back to top](#table-of-contents) + ### distinctValuesOfArray Returns all the distinct values of an array. @@ -252,12 +271,12 @@ const distinctValuesOfArray = arr => [...new Set(arr)]; Removes elements in an array until the passed function returns `true`. Returns the remaining elements in the 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`. +Loop through the array, using `Array.slice()` 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(); + while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1); return arr; }; // dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4] @@ -265,6 +284,21 @@ const dropElements = (arr, func) => { [⬆ back to top](#table-of-contents) +### dropRight + +Returns a new array with `n` elements removed from the right + +Check if `n` is shorter than the given array and use `Array.slice()` to slice it accordingly or return an empty array. + +```js +const dropRight = (arr, n = 1) => n < arr.length ? arr.slice(0, arr.length - n) : [] +//dropRight([1,2,3]) -> [1,2] +//dropRight([1,2,3], 2) -> [1] +//dropRight([1,2,3], 42) -> [] +``` + +[⬆ back to top](#table-of-contents) + ### everyNth Returns every nth element in an array. @@ -367,15 +401,16 @@ const initial = arr => arr.slice(0, -1); ### initializeArrayWithRange -Initializes an array containing the numbers in the specified range. +Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive. -Use `Array(end-start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. +Use `Array((end + 1) - 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 initializeArrayWithRange = (end, start = 0) => - Array.from({ length: end - start }).map((v, i) => i + start); -// initializeArrayWithRange(5) -> [0,1,2,3,4] +const initializeArrayWithRange = (end, start = 0) => + Array.from({ length: (end + 1) - start }).map((v, i) => i + start); +// initializeArrayWithRange(5) -> [0,1,2,3,4,5] +// initializeArrayWithRange(7, 3) -> [3,4,5,6,7] ``` [⬆ back to top](#table-of-contents) @@ -474,14 +509,75 @@ Mutates the original array to filter out the values specified. Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. Use `Array.length = 0` to mutate the passed in array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. +_(For a snippet that does not mutate the original array see [`without`](#without))_ + ```js const pull = (arr, ...args) => { - let pulled = arr.filter((v, i) => !args.includes(v)); + let pulled = arr.filter((v, i) => !args.toString().split(',').includes(v)); arr.length = 0; pulled.forEach(v => arr.push(v)); }; -// let myArray = ['a', 'b', 'c', 'a', 'b', 'c']; -// pull(myArray, 'a', 'c'); -// console.log(myArray) -> [ 'b', 'b' ] + +// let myArray1 = ['a', 'b', 'c', 'a', 'b', 'c']; +// pull(myArray1, 'a', 'c'); +// console.log(myArray1) -> [ 'b', 'b' ] + +// let myArray2 = ['a', 'b', 'c', 'a', 'b', 'c']; +// pull(myArray2, ['a', 'c']); +// console.log(myArray2) -> [ 'b', 'b' ] +``` + +[⬆ back to top](#table-of-contents) + +### pullAtIndex + +Mutates the original array to filter out the values at the specified indexes. + +Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. +Use `Array.length = 0` to mutate the passed in array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. +Use `Array.push()` to keep track of pulled values + +```js +const pullAtIndex = (arr, pullArr) => { + let removed = []; + let pulled = arr.map((v, i) => pullArr.includes(i) ? removed.push(v) : v) + .filter((v, i) => !pullArr.includes(i)) + arr.length = 0; + pulled.forEach(v => arr.push(v)); + return removed; +} + +// let myArray = ['a', 'b', 'c', 'd']; +// let pulled = pullAtIndex(myArray, [1, 3]); + +// console.log(myArray); -> [ 'a', 'c' ] +// console.log(pulled); -> [ 'b', 'd' ] +``` + +[⬆ back to top](#table-of-contents) + +### pullAtValue + +Mutates the original array to filter out the values specified. Returns the removed elements. + +Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. +Use `Array.length = 0` to mutate the passed in array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. +Use `Array.push()` to keep track of pulled values + +```js +const pullAtValue = (arr, pullArr) => { + let removed = [], + pushToRemove = arr.forEach((v, i) => pullArr.includes(v) ? removed.push(v) : v), + mutateTo = arr.filter((v, i) => !pullArr.includes(v)); + arr.length = 0; + mutateTo.forEach(v => arr.push(v)); + return removed; +} +/* +let myArray = ['a', 'b', 'c', 'd']; +let pulled = pullAtValue(myArray, ['b', 'd']); +console.log(myArray); -> [ 'a', 'c' ] +console.log(pulled); -> [ 'b', 'd' ] +*/ ``` [⬆ back to top](#table-of-contents) @@ -621,6 +717,8 @@ Filters out the elements of an array, that have one of the specified values. Use `Array.filter()` to create an array excluding(using `!Array.includes()`) all given values. +_(For a snippet that mutates the original array see [`pull`](#pull))_ + ```js const without = (arr, ...args) => arr.filter(v => !args.includes(v)); // without([2, 1, 2, 3], 1, 2) -> [3] @@ -658,7 +756,7 @@ Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of t ```js const bottomVisible = () => - document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; + document.documentElement.clientHeight + window.scrollY >= (document.documentElement.scrollHeight || document.documentElement.clientHeight); // bottomVisible() -> true ``` @@ -1144,7 +1242,7 @@ Return the number at the midpoint if `length` is odd, otherwise the average of t ```js const median = arr => { - const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); + const mid = Math.floor(arr.length / 2), nums = [...arr].sort((a, b) => a - b); return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; }; // median([5,6,50,1,-5]) -> 5 @@ -1373,6 +1471,22 @@ const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); [⬆ back to top](#table-of-contents) +### select + +Retrieve a property that indicated by the selector from object. + +If property not exists returns `undefined`. + +```js +const select = (from, selector) => + selector.split('.').reduce((prev, cur) => prev && prev[cur], from); + +// const obj = {selector: {to: {val: 'val to select'}}}; +// select(obj, 'selector.to.val'); -> 'val to select' +``` + +[⬆ back to top](#table-of-contents) + ### shallowClone Creates a shallow clone of an object. @@ -1460,8 +1574,7 @@ Retuns `number` of vowels in provided string. Use a regular expression to count number of vowels `(A, E, I, O, U)` in a `string`. ```js -const countVowels = str => - return (str.match(/[aeiou]/ig) || []).length; +const countVowels = str => (str.match(/[aeiou]/ig) || []).length; // countVowels('foobar') -> 3 // countVowels('gym') -> 0 ``` @@ -1503,11 +1616,11 @@ const fromCamelCase = (str, separator = '_') => Reverses a string. -Use array destructuring and `Array.reverse()` to reverse the order of the characters in the string. +Use `split('')` and `Array.reverse()` to reverse the order of the characters in the string. Combine characters to get a string using `join('')`. ```js -const reverseString = str => [...str].reverse().join(''); +const reverseString = str => str.split('').reverse().join(''); // reverseString('foobar') -> 'raboof' ``` @@ -1618,19 +1731,26 @@ const getType = v => ### hexToRGB -Converts a colorcode to a `rgb()` string. +Converts a color code to a `rgb()` or `rgba()` string if alpha value is provided. -Use bitwise right-shift operator and mask bits with `&` (and) operator to convert a hexadecimal color code (prefixed with `#`) to a string with the RGB values. In case it's a 3-digit-colorcode, do the same with the 6-digit-colorcode extended by the extendHex() function (ref. `extendHex` snippet) +Use bitwise right-shift operator and mask bits with `&` (and) operator to convert a hexadecimal color code (with or without prefixed with `#`) to a string with the RGB values. If it's 3-digit color code, first convert to 6-digit version. If any alpha value is provided alongside 6-digit hex, give `rgba()` string in return. ```js -const hexToRgb = hex => { - const extendHex = shortHex => - '#' + shortHex.slice(shortHex.startsWith('#') ? 1 : 0).split('').map(x => x+x).join(''); - const extendedHex = hex.slice(hex.startsWith('#') ? 1 : 0).length === 3 ? extendHex(hex) : hex; - return `rgb(${parseInt(extendedHex.slice(1), 16) >> 16}, ${(parseInt(extendedHex.slice(1), 16) & 0x00ff00) >> 8}, ${parseInt(extendedHex.slice(1), 16) & 0x0000ff})`; -} -// hexToRgb('#27ae60') -> 'rgb(39, 174, 96)' -// hexToRgb('#acd') -> 'rgb(170, 204, 221)' +const hexToRGB = hex => { + let alpha = false, h = hex.slice(hex.startsWith('#') ? 1 : 0); + if (h.length === 3) h = [...h].map(x => x + x).join(''); + else if (h.length === 8) alpha = true; + h = parseInt(h, 16); + return 'rgb' + (alpha ? 'a' : '') + '(' + + (h >>> (alpha ? 24 : 16)) + ', ' + + ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + ', ' + + ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) + + (alpha ? `, ${(h & 0x000000ff)}` : '') + ')'; +}; +// hexToRGB('#27ae60ff') -> 'rgba(39, 174, 96, 255)' +// hexToRGB('27ae60') -> 'rgb(39, 174, 96)' +// hexToRGB('#fff') -> 'rgb(255, 255, 255)' + ``` [⬆ back to top](#table-of-contents) diff --git a/docs/index.html b/docs/index.html index cabdd7c23..38b5a08ac 100644 --- a/docs/index.html +++ b/docs/index.html @@ -17,16 +17,19 @@ html, * { font-family: 'Poppins', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif; } code, pre, kbd, code *, pre *, kbd * { font-family: 'Inconsolata', Menlo, Consolas, monospace; } code, kbd { font-size: 1em; } + code { transform: scale(1); } /* Deals with the issue described in #243 */ pre { font-size: 1rem; border: 0.0625rem solid var(--secondary-border-color); border-radius: var(--universal-border-radius);} -
-

 30 seconds of code

+
+

 30 seconds of code + Curated collection of useful Javascript snippets that you can understand in 30 seconds or less. +

-
+

Array

+
 

Array

arrayMax

Returns the maximum value in an array.

Use Math.max() combined with the spread operator (...) to get the maximum value in the array.

@@ -208,6 +216,12 @@ Recursively flatten each element that is an array.

const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); };
 // difference([1,2,3], [1,2,4]) -> [3]
 
+

differenceWith

+

Filters out all values from an array for which the comparator function does not return true.

+

Use Array.filter() and Array.find() to find the appropriate values.

+
const differenceWith = (arr, val, comp) => arr.filter(a => !val.find(b => comp(a, b)))
+// differenceWith([1, 1.2, 1.5, 3], [1.9, 3], (a,b) => Math.round(a) == Math.round(b)) -> [1, 1.2]
+

distinctValuesOfArray

Returns all the distinct values of an array.

Use ES6 Set and the ...rest operator to discard all duplicated values.

@@ -216,14 +230,22 @@ Recursively flatten each element that is an array.


dropElements

Removes elements in an array until the passed function returns true. Returns the remaining elements in the 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. +

Loop through the array, using Array.slice() to drop the first element of the array until the returned value from the function is true. Returns the remaining elements.

const dropElements = (arr, func) => {
-  while (arr.length > 0 && !func(arr[0])) arr.shift();
+  while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1);
   return arr;
 };
 // dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4]
 
+

dropRight

+

Returns a new array with n elements removed from the right

+

Check if n is shorter than the given array and use Array.slice() to slice it accordingly or return an empty array.

+
const dropRight = (arr, n = 1) => n < arr.length ? arr.slice(0, arr.length - n) : []
+//dropRight([1,2,3]) -> [1,2]
+//dropRight([1,2,3], 2) -> [1]
+//dropRight([1,2,3], 42) -> []
+

everyNth

Returns every nth element in an array.

Use Array.filter() to create a new array that contains every nth element of a given array.

@@ -276,12 +298,13 @@ Use Array.reduce() to create an object, where the keys are produced // initial([1,2,3]) -> [1,2]

initializeArrayWithRange

-

Initializes an array containing the numbers in the specified range.

-

Use Array(end-start) to create an array of the desired length, Array.map() to fill with the desired values in a range. +

Initializes an array containing the numbers in the specified range where start and end are inclusive.

+

Use Array((end + 1) - 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.

-
const initializeArrayWithRange = (end, start = 0) =>
-  Array.from({ length: end - start }).map((v, i) => i + start);
-// initializeArrayWithRange(5) -> [0,1,2,3,4]
+
const initializeArrayWithRange = (end, start = 0) => 
+  Array.from({ length: (end + 1) - start }).map((v, i) => i + start);
+// initializeArrayWithRange(5) -> [0,1,2,3,4,5]
+// initializeArrayWithRange(7, 3) -> [3,4,5,6,7]
 

initializeArrayWithValues

Initializes and fills an array with the specified values.

@@ -332,13 +355,59 @@ Omit the second argument, n, to get the first element of the array.

Mutates the original array to filter out the values specified.

Use Array.filter() and Array.includes() to pull out the values that are not needed. Use Array.length = 0 to mutate the passed in array by resetting it's length to zero and Array.push() to re-populate it with only the pulled values.

+

(For a snippet that does not mutate the original array see without)

const pull = (arr, ...args) => {
-  let pulled = arr.filter((v, i) => !args.includes(v));
+  let pulled = arr.filter((v, i) => !args.toString().split(',').includes(v));
   arr.length = 0; pulled.forEach(v => arr.push(v));
 };
-// let myArray = ['a', 'b', 'c', 'a', 'b', 'c'];
-// pull(myArray, 'a', 'c');
-// console.log(myArray) -> [ 'b', 'b' ]
+
+// let myArray1 = ['a', 'b', 'c', 'a', 'b', 'c'];
+// pull(myArray1, 'a', 'c');
+// console.log(myArray1) -> [ 'b', 'b' ]
+
+// let myArray2 = ['a', 'b', 'c', 'a', 'b', 'c'];
+// pull(myArray2, ['a', 'c']);
+// console.log(myArray2) -> [ 'b', 'b' ]
+
+

pullAtIndex

+

Mutates the original array to filter out the values at the specified indexes.

+

Use Array.filter() and Array.includes() to pull out the values that are not needed. +Use Array.length = 0 to mutate the passed in array by resetting it's length to zero and Array.push() to re-populate it with only the pulled values. +Use Array.push() to keep track of pulled values

+
const pullAtIndex = (arr, pullArr) => {
+  let removed = [];
+  let pulled = arr.map((v, i) => pullArr.includes(i) ? removed.push(v) : v)
+                  .filter((v, i) => !pullArr.includes(i))
+  arr.length = 0; 
+  pulled.forEach(v => arr.push(v));
+  return removed;
+}
+
+// let myArray = ['a', 'b', 'c', 'd'];
+// let pulled = pullAtIndex(myArray, [1, 3]);
+
+// console.log(myArray); -> [ 'a', 'c' ]
+// console.log(pulled); -> [ 'b', 'd' ]
+
+

pullAtValue

+

Mutates the original array to filter out the values specified. Returns the removed elements.

+

Use Array.filter() and Array.includes() to pull out the values that are not needed. +Use Array.length = 0 to mutate the passed in array by resetting it's length to zero and Array.push() to re-populate it with only the pulled values. +Use Array.push() to keep track of pulled values

+
const pullAtValue = (arr, pullArr) => {
+  let removed = [], 
+    pushToRemove = arr.forEach((v, i) => pullArr.includes(v) ? removed.push(v) : v),
+    mutateTo = arr.filter((v, i) => !pullArr.includes(v));
+  arr.length = 0;
+  mutateTo.forEach(v => arr.push(v));
+  return removed;
+}
+/*
+let myArray = ['a', 'b', 'c', 'd'];
+let pulled = pullAtValue(myArray, ['b', 'd']);
+console.log(myArray); -> [ 'a', 'c' ]
+console.log(pulled); -> [ 'b', 'd' ]
+*/
 

remove

Removes elements from an array for which the given function returns false.

@@ -409,6 +478,7 @@ This method also works with strings.


without

Filters out the elements of an array, that have one of the specified values.

Use Array.filter() to create an array excluding(using !Array.includes()) all given values.

+

(For a snippet that mutates the original array see pull)

const without = (arr, ...args) => arr.filter(v => !args.includes(v));
 // without([2, 1, 2, 3], 1, 2) -> [3]
 
@@ -431,7 +501,7 @@ If lengths of the argument-arrays vary, undefined is used where no

Returns true if the bottom of the page is visible, false otherwise.

Use scrollY, scrollHeight and clientHeight to determine if the bottom of the page is visible.

const bottomVisible = () =>
-  document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight;
+  document.documentElement.clientHeight + window.scrollY >= (document.documentElement.scrollHeight || document.documentElement.clientHeight);
 // bottomVisible() -> true
 

currentURL

@@ -706,7 +776,7 @@ The GCD formula uses recursion.

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.

const median = arr => {
-  const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b);
+  const mid = Math.floor(arr.length / 2), nums = [...arr].sort((a, b) => a - b);
   return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
 };
 // median([5,6,50,1,-5]) -> 5
@@ -840,6 +910,15 @@ Also if you give it a special key (childIndicator) it will search d
 
const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]);
 // objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]])
 
+

select

+

Retrieve a property that indicated by the selector from object.

+

If property not exists returns undefined.

+
const select = (from, selector) =>
+  selector.split('.').reduce((prev, cur) => prev && prev[cur], from);
+
+// const obj = {selector: {to: {val: 'val to select'}}};
+// select(obj, 'selector.to.val'); -> 'val to select'
+

shallowClone

Creates a shallow clone of an object.

Use Object.assign() and an empty object ({}) to create a shallow clone of the original.

@@ -888,8 +967,7 @@ Omit the lowerRest parameter to keep the rest of the string intact,

countVowels

Retuns number of vowels in provided string.

Use a regular expression to count number of vowels (A, E, I, O, U) in a string.

-
const countVowels = str =>
-  return (str.match(/[aeiou]/ig) || []).length;
+
const countVowels = str => (str.match(/[aeiou]/ig) || []).length;
 // countVowels('foobar') -> 3
 // countVowels('gym') -> 0
 
@@ -912,9 +990,9 @@ Omit the second argument to use a default separator of _.


reverseString

Reverses a string.

-

Use array destructuring and Array.reverse() to reverse the order of the characters in the string. +

Use split('') and Array.reverse() to reverse the order of the characters in the string. Combine characters to get a string using join('').

-
const reverseString = str => [...str].reverse().join('');
+
const reverseString = str => str.split('').reverse().join('');
 // reverseString('foobar') -> 'raboof'
 

sortCharactersInString

@@ -973,16 +1051,23 @@ Return the string truncated to the desired length, with ... appende // getType(new Set([1,2,3])) -> "set"

hexToRGB

-

Converts a colorcode to a rgb() string.

-

Use bitwise right-shift operator and mask bits with & (and) operator to convert a hexadecimal color code (prefixed with #) to a string with the RGB values. In case it's a 3-digit-colorcode, do the same with the 6-digit-colorcode extended by the extendHex() function (ref. extendHex snippet)

-
const hexToRgb = hex => {
-  const extendHex = shortHex =>
-    '#' + shortHex.slice(shortHex.startsWith('#') ? 1 : 0).split('').map(x => x+x).join('');
-  const extendedHex = hex.slice(hex.startsWith('#') ? 1 : 0).length === 3 ? extendHex(hex) : hex;
-  return `rgb(${parseInt(extendedHex.slice(1), 16) >> 16}, ${(parseInt(extendedHex.slice(1), 16) & 0x00ff00) >> 8}, ${parseInt(extendedHex.slice(1), 16) & 0x0000ff})`;
-}
-// hexToRgb('#27ae60') -> 'rgb(39, 174, 96)'
-// hexToRgb('#acd') -> 'rgb(170, 204, 221)'
+

Converts a color code to a rgb() or rgba() string if alpha value is provided.

+

Use bitwise right-shift operator and mask bits with & (and) operator to convert a hexadecimal color code (with or without prefixed with #) to a string with the RGB values. If it's 3-digit color code, first convert to 6-digit version. If any alpha value is provided alongside 6-digit hex, give rgba() string in return.

+
const hexToRGB = hex => {
+  let alpha = false, h = hex.slice(hex.startsWith('#') ? 1 : 0);
+  if (h.length === 3) h = [...h].map(x => x + x).join('');
+  else if (h.length === 8) alpha = true;
+  h = parseInt(h, 16);
+  return 'rgb' + (alpha ? 'a' : '') + '('
+    + (h >>> (alpha ? 24 : 16)) + ', '
+    + ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + ', '
+    + ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0))
+    + (alpha ? `, ${(h & 0x000000ff)}` : '') + ')';
+};
+// hexToRGB('#27ae60ff') -> 'rgba(39, 174, 96, 255)'
+// hexToRGB('27ae60') -> 'rgb(39, 174, 96)'
+// hexToRGB('#fff') -> 'rgb(255, 255, 255)'
+
 

isArray

Checks if the given argument is an array.

@@ -1081,9 +1166,12 @@ Use Number() to check if the coercion holds.

// validateNumber('10') -> true

- +
-
+
diff --git a/scripts/web-script.js b/scripts/web-script.js index edc221de3..27e84fcc4 100644 --- a/scripts/web-script.js +++ b/scripts/web-script.js @@ -60,6 +60,7 @@ try { output += '\n'; } output += `
`; + output += ` `; // Loop over tags and snippets to create the list of snippets for(let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))].filter(v => v).sort((a,b) => a.localeCompare(b))){ output +=md.render(`## ${capitalize(tag, true)}\n`).replace(/

/g,'

'); diff --git a/snippets/bottomVisible.md b/snippets/bottomVisible.md index 8e655db45..adac44881 100644 --- a/snippets/bottomVisible.md +++ b/snippets/bottomVisible.md @@ -6,6 +6,6 @@ Use `scrollY`, `scrollHeight` and `clientHeight` to determine if the bottom of t ```js const bottomVisible = () => - document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; + document.documentElement.clientHeight + window.scrollY >= (document.documentElement.scrollHeight || document.documentElement.clientHeight); // bottomVisible() -> true ``` diff --git a/snippets/differenceWith.md b/snippets/differenceWith.md new file mode 100644 index 000000000..ba4aac0ec --- /dev/null +++ b/snippets/differenceWith.md @@ -0,0 +1,10 @@ +### differenceWith + +Filters out all values from an array for which the comparator function does not return `true`. + +Use `Array.filter()` and `Array.find()` to find the appropriate values. + +```js +const differenceWith = (arr, val, comp) => arr.filter(a => !val.find(b => comp(a, b))) +// differenceWith([1, 1.2, 1.5, 3], [1.9, 3], (a,b) => Math.round(a) == Math.round(b)) -> [1, 1.2] +``` diff --git a/snippets/dropElements.md b/snippets/dropElements.md index 34138eb93..adc81d79d 100644 --- a/snippets/dropElements.md +++ b/snippets/dropElements.md @@ -2,12 +2,12 @@ Removes elements in an array until the passed function returns `true`. Returns the remaining elements in the 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`. +Loop through the array, using `Array.slice()` 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(); + while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1); return arr; }; // dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4] diff --git a/snippets/dropRight.md b/snippets/dropRight.md new file mode 100644 index 000000000..d1a56d764 --- /dev/null +++ b/snippets/dropRight.md @@ -0,0 +1,12 @@ +### dropRight + +Returns a new array with `n` elements removed from the right + +Check if `n` is shorter than the given array and use `Array.slice()` to slice it accordingly or return an empty array. + +```js +const dropRight = (arr, n = 1) => n < arr.length ? arr.slice(0, arr.length - n) : [] +//dropRight([1,2,3]) -> [1,2] +//dropRight([1,2,3], 2) -> [1] +//dropRight([1,2,3], 42) -> [] +``` diff --git a/snippets/hexToRGB.md b/snippets/hexToRGB.md index 273aafd21..2d08b4321 100644 --- a/snippets/hexToRGB.md +++ b/snippets/hexToRGB.md @@ -1,16 +1,23 @@ ### hexToRGB -Converts a colorcode to a `rgb()` string. +Converts a color code to a `rgb()` or `rgba()` string if alpha value is provided. -Use bitwise right-shift operator and mask bits with `&` (and) operator to convert a hexadecimal color code (prefixed with `#`) to a string with the RGB values. In case it's a 3-digit-colorcode, do the same with the 6-digit-colorcode extended by the extendHex() function (ref. `extendHex` snippet) +Use bitwise right-shift operator and mask bits with `&` (and) operator to convert a hexadecimal color code (with or without prefixed with `#`) to a string with the RGB values. If it's 3-digit color code, first convert to 6-digit version. If any alpha value is provided alongside 6-digit hex, give `rgba()` string in return. ```js -const hexToRgb = hex => { - const extendHex = shortHex => - '#' + shortHex.slice(shortHex.startsWith('#') ? 1 : 0).split('').map(x => x+x).join(''); - const extendedHex = hex.slice(hex.startsWith('#') ? 1 : 0).length === 3 ? extendHex(hex) : hex; - return `rgb(${parseInt(extendedHex.slice(1), 16) >> 16}, ${(parseInt(extendedHex.slice(1), 16) & 0x00ff00) >> 8}, ${parseInt(extendedHex.slice(1), 16) & 0x0000ff})`; -} -// hexToRgb('#27ae60') -> 'rgb(39, 174, 96)' -// hexToRgb('#acd') -> 'rgb(170, 204, 221)' +const hexToRGB = hex => { + let alpha = false, h = hex.slice(hex.startsWith('#') ? 1 : 0); + if (h.length === 3) h = [...h].map(x => x + x).join(''); + else if (h.length === 8) alpha = true; + h = parseInt(h, 16); + return 'rgb' + (alpha ? 'a' : '') + '(' + + (h >>> (alpha ? 24 : 16)) + ', ' + + ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + ', ' + + ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) + + (alpha ? `, ${(h & 0x000000ff)}` : '') + ')'; +}; +// hexToRGB('#27ae60ff') -> 'rgba(39, 174, 96, 255)' +// hexToRGB('27ae60') -> 'rgb(39, 174, 96)' +// hexToRGB('#fff') -> 'rgb(255, 255, 255)' + ``` diff --git a/snippets/initializeArrayWithRange.md b/snippets/initializeArrayWithRange.md index 75dbc8adf..c3ef5a0a0 100644 --- a/snippets/initializeArrayWithRange.md +++ b/snippets/initializeArrayWithRange.md @@ -1,12 +1,13 @@ ### initializeArrayWithRange -Initializes an array containing the numbers in the specified range. +Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive. -Use `Array(end-start)` to create an array of the desired length, `Array.map()` to fill with the desired values in a range. +Use `Array((end + 1) - 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 initializeArrayWithRange = (end, start = 0) => - Array.from({ length: end - start }).map((v, i) => i + start); -// initializeArrayWithRange(5) -> [0,1,2,3,4] +const initializeArrayWithRange = (end, start = 0) => + Array.from({ length: (end + 1) - start }).map((v, i) => i + start); +// initializeArrayWithRange(5) -> [0,1,2,3,4,5] +// initializeArrayWithRange(7, 3) -> [3,4,5,6,7] ``` diff --git a/snippets/median.md b/snippets/median.md index fd8ca3d7c..c7eea609c 100644 --- a/snippets/median.md +++ b/snippets/median.md @@ -7,7 +7,7 @@ Return the number at the midpoint if `length` is odd, otherwise the average of t ```js const median = arr => { - const mid = Math.floor(arr.length / 2), nums = arr.sort((a, b) => a - b); + const mid = Math.floor(arr.length / 2), nums = [...arr].sort((a, b) => a - b); return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; }; // median([5,6,50,1,-5]) -> 5 diff --git a/snippets/pull.md b/snippets/pull.md index 4913c5082..16f0e25c4 100644 --- a/snippets/pull.md +++ b/snippets/pull.md @@ -5,12 +5,19 @@ Mutates the original array to filter out the values specified. Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. Use `Array.length = 0` to mutate the passed in array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. +_(For a snippet that does not mutate the original array see [`without`](#without))_ + ```js const pull = (arr, ...args) => { - let pulled = arr.filter((v, i) => !args.includes(v)); + let pulled = arr.filter((v, i) => !args.toString().split(',').includes(v)); arr.length = 0; pulled.forEach(v => arr.push(v)); }; -// let myArray = ['a', 'b', 'c', 'a', 'b', 'c']; -// pull(myArray, 'a', 'c'); -// console.log(myArray) -> [ 'b', 'b' ] + +// let myArray1 = ['a', 'b', 'c', 'a', 'b', 'c']; +// pull(myArray1, 'a', 'c'); +// console.log(myArray1) -> [ 'b', 'b' ] + +// let myArray2 = ['a', 'b', 'c', 'a', 'b', 'c']; +// pull(myArray2, ['a', 'c']); +// console.log(myArray2) -> [ 'b', 'b' ] ``` diff --git a/snippets/pullAtIndex.md b/snippets/pullAtIndex.md new file mode 100644 index 000000000..0e0d8cf7f --- /dev/null +++ b/snippets/pullAtIndex.md @@ -0,0 +1,24 @@ +### pullAtIndex + +Mutates the original array to filter out the values at the specified indexes. + +Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. +Use `Array.length = 0` to mutate the passed in array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. +Use `Array.push()` to keep track of pulled values + +```js +const pullAtIndex = (arr, pullArr) => { + let removed = []; + let pulled = arr.map((v, i) => pullArr.includes(i) ? removed.push(v) : v) + .filter((v, i) => !pullArr.includes(i)) + arr.length = 0; + pulled.forEach(v => arr.push(v)); + return removed; +} + +// let myArray = ['a', 'b', 'c', 'd']; +// let pulled = pullAtIndex(myArray, [1, 3]); + +// console.log(myArray); -> [ 'a', 'c' ] +// console.log(pulled); -> [ 'b', 'd' ] +``` diff --git a/snippets/pullAtValue.md b/snippets/pullAtValue.md new file mode 100644 index 000000000..64798068f --- /dev/null +++ b/snippets/pullAtValue.md @@ -0,0 +1,24 @@ +### pullAtValue + +Mutates the original array to filter out the values specified. Returns the removed elements. + +Use `Array.filter()` and `Array.includes()` to pull out the values that are not needed. +Use `Array.length = 0` to mutate the passed in array by resetting it's length to zero and `Array.push()` to re-populate it with only the pulled values. +Use `Array.push()` to keep track of pulled values + +```js +const pullAtValue = (arr, pullArr) => { + let removed = [], + pushToRemove = arr.forEach((v, i) => pullArr.includes(v) ? removed.push(v) : v), + mutateTo = arr.filter((v, i) => !pullArr.includes(v)); + arr.length = 0; + mutateTo.forEach(v => arr.push(v)); + return removed; +} +/* +let myArray = ['a', 'b', 'c', 'd']; +let pulled = pullAtValue(myArray, ['b', 'd']); +console.log(myArray); -> [ 'a', 'c' ] +console.log(pulled); -> [ 'b', 'd' ] +*/ +``` diff --git a/snippets/reverseString.md b/snippets/reverseString.md index a76c506db..5564a5897 100644 --- a/snippets/reverseString.md +++ b/snippets/reverseString.md @@ -2,10 +2,10 @@ Reverses a string. -Use array destructuring and `Array.reverse()` to reverse the order of the characters in the string. +Use `split('')` and `Array.reverse()` to reverse the order of the characters in the string. Combine characters to get a string using `join('')`. ```js -const reverseString = str => [...str].reverse().join(''); +const reverseString = str => str.split('').reverse().join(''); // reverseString('foobar') -> 'raboof' ``` diff --git a/snippets/select.md b/snippets/select.md new file mode 100644 index 000000000..6f60f4d95 --- /dev/null +++ b/snippets/select.md @@ -0,0 +1,13 @@ +### select + +Retrieve a property that indicated by the selector from object. + +If property not exists returns `undefined`. + +```js +const select = (from, selector) => + selector.split('.').reduce((prev, cur) => prev && prev[cur], from); + +// const obj = {selector: {to: {val: 'val to select'}}}; +// select(obj, 'selector.to.val'); -> 'val to select' +``` diff --git a/snippets/without.md b/snippets/without.md index 70f2a20aa..532ec26d9 100644 --- a/snippets/without.md +++ b/snippets/without.md @@ -4,6 +4,8 @@ Filters out the elements of an array, that have one of the specified values. Use `Array.filter()` to create an array excluding(using `!Array.includes()`) all given values. +_(For a snippet that mutates the original array see [`pull`](#pull))_ + ```js const without = (arr, ...args) => arr.filter(v => !args.includes(v)); // without([2, 1, 2, 3], 1, 2) -> [3] diff --git a/static-parts/README-start.md b/static-parts/README-start.md index 6a6504483..92eb9fe8a 100644 --- a/static-parts/README-start.md +++ b/static-parts/README-start.md @@ -6,5 +6,6 @@ - Use Ctrl + F or command + F to search for a snippet. - Contributions welcome, please read the [contribution guide](CONTRIBUTING.md). - Snippets are written in ES6, use the [Babel transpiler](https://babeljs.io/) to ensure backwards-compatibility. +- You can import these snippets into Alfred 3, using [this file](https://github.com/lslvxy/30-seconds-of-code-alfredsnippets). ## Table of Contents diff --git a/static-parts/index-end.html b/static-parts/index-end.html index 1dd086328..6ea0075e4 100644 --- a/static-parts/index-end.html +++ b/static-parts/index-end.html @@ -1,6 +1,9 @@ - +

- + diff --git a/static-parts/index-start.html b/static-parts/index-start.html index 0aeee1e31..7b4228dbd 100644 --- a/static-parts/index-start.html +++ b/static-parts/index-start.html @@ -17,16 +17,19 @@ html, * { font-family: 'Poppins', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif; } code, pre, kbd, code *, pre *, kbd * { font-family: 'Inconsolata', Menlo, Consolas, monospace; } code, kbd { font-size: 1em; } + code { transform: scale(1); } /* Deals with the issue described in #243 */ pre { font-size: 1rem; border: 0.0625rem solid var(--secondary-border-color); border-radius: var(--universal-border-radius);} -
-

 30 seconds of code

+
+

 30 seconds of code + Curated collection of useful Javascript snippets that you can understand in 30 seconds or less. +

-
+