diff --git a/README.md b/README.md index 7083b13b8..5194f20c3 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,8 @@ average(1, 2, 3);
View contents +* [`bifurcate`](#bifurcate) +* [`bifurcateBy`](#bifurcateby) * [`chunk`](#chunk) * [`compact`](#compact) * [`countBy`](#countby) @@ -246,6 +248,7 @@ average(1, 2, 3); * [`sleep`](#sleep) * [`throttle`](#throttle) * [`times`](#times) +* [`uncurry`](#uncurry) * [`unfold`](#unfold)
@@ -255,9 +258,12 @@ average(1, 2, 3);
View contents +* [`approximatelyEqual`](#approximatelyequal) * [`average`](#average) * [`averageBy`](#averageby) +* [`binomialCoefficient`](#binomialcoefficient) * [`clampNumber`](#clampnumber) +* [`degreesToRads`](#degreestorads) * [`digitize`](#digitize) * [`distance`](#distance) * [`elo`](#elo-) @@ -278,6 +284,7 @@ average(1, 2, 3); * [`percentile`](#percentile) * [`powerset`](#powerset) * [`primes`](#primes) +* [`radsToDegrees`](#radstodegrees) * [`randomIntArrayInRange`](#randomintarrayinrange) * [`randomIntegerInRange`](#randomintegerinrange) * [`randomNumberInRange`](#randomnumberinrange) @@ -760,6 +767,52 @@ const unary = fn => val => fn(val); --- ## 📚 Array +### bifurcate + +Splits values into two groups. If an element in `filter` is truthy, the corresponding element in the collection belongs to the first group; otherwise, it belongs to the second group. + +Use `Array.reduce()` and `Array.push()` to add elements to groups, based on `filter`. + +```js +const bifurcate = (arr, filter) => + arr.reduce((acc, val, i) => (acc[filter[i] ? 0 : 1].push(val), acc), [[], []]); +``` + +
+Examples + +```js +bifurcate(['beep', 'boop', 'foo', 'bar'], [true, true, false, true]); // [ ['beep', 'boop', 'bar'], ['foo'] ] +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + +### bifurcateBy + +Splits values into two groups according to a predicate function, which specifies which group an element in the input collection belongs to. If the predicate function returns a truthy value, the collection element belongs to the first group; otherwise, it belongs to the second group. + +Use `Array.reduce()` and `Array.push()` to add elements to groups, based on the value returned by `fn` for each element. + +```js +const bifurcateBy = (arr, fn) => + arr.reduce((acc, val, i) => (acc[fn(val, i) ? 0 : 1].push(val), acc), [[], []]); +``` + +
+Examples + +```js +bifurcateBy(['beep', 'boop', 'foo', 'bar'], x => x[0] === 'b'); // [ ['beep', 'boop', 'bar'], ['foo'] ] +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### chunk Chunks an array into smaller arrays of a specified size. @@ -4199,6 +4252,38 @@ console.log(output); // 01234
[⬆ Back to top](#table-of-contents) +### uncurry + +Uncurries a function up to depth `n`. + +Return a variadic function. +Use `Array.reduce()` on the provided arguments to call each subsequent curry level of the function. +If the `length` of the provided arguments is less than `n` throw an error. +Otherwise, call `fn` with the proper amount of arguments, using `Array.slice(0, n)`. +Omit the second argument, `n`, to uncurry up to depth `1`. + +```js +const uncurry = (fn, n = 1) => (...args) => { + const next = acc => args => args.reduce((x, y) => x(y), acc); + if (n > args.length) throw new RangeError('Arguments too few!'); + return next(fn)(args.slice(0, n)); +}; +``` + +
+Examples + +```js +const add = x => y => z => x + y + z; +const uncurriedAdd = uncurry(add, 3); +uncurriedAdd(1, 2, 3); // 6 +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### unfold Builds an array, using an iterator function and an initial seed value. @@ -4230,6 +4315,29 @@ unfold(f, 10); // [-10, -20, -30, -40, -50] --- ## ➗ Math +### approximatelyEqual + +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 parameter, `epsilon`, to use a default value of `0.001`. + +```js +const approximatelyEqual = (v1, v2, epsilon = 0.001) => Math.abs(v1 - v2) < epsilon; +``` + +
+Examples + +```js +approximatelyEqual(Math.PI / 2.0, 1.5708); // true +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### average Returns the average of two or more numbers. @@ -4278,6 +4386,41 @@ averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 5
[⬆ Back to top](#table-of-contents) +### binomialCoefficient + +Evaluates the binomial coefficient of two integers `n` and `k`. + +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); +}; +``` + +
+Examples + +```js +binomialCoefficient(8, 2); // 28 +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### clampNumber Clamps `num` within the inclusive range specified by the boundary values `a` and `b`. @@ -4302,6 +4445,28 @@ clampNumber(1, -1, -5); // -1
[⬆ Back to top](#table-of-contents) +### degreesToRads + +Converts an angle from degrees to radians. + +Use `Math.PI` and the degree to radian formula to convert the angle from degrees to radians. + +```js +const degreesToRads = deg => deg * Math.PI / 180.0; +``` + +
+Examples + +```js +degreesToRads(90.0); // ~1.5708 +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### digitize Converts a number to an array of digits. @@ -4850,6 +5015,28 @@ primes(10); // [2,3,5,7]
[⬆ Back to top](#table-of-contents) +### radsToDegrees + +Converts an angle from radians to degrees. + +Use `Math.PI` and the radian to degree formula to convert the angle from radians to degrees. + +```js +const radsToDegrees = rad => rad * 180.0 / Math.PI; +``` + +
+Examples + +```js +radsToDegrees(Math.PI / 2); // 90 +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### randomIntArrayInRange Returns an array of n random integers in the specified range. diff --git a/docs/index.html b/docs/index.html index 385f479a6..75890c2f5 100644 --- a/docs/index.html +++ b/docs/index.html @@ -50,7 +50,7 @@ scrollToTop(); } }, false); - }

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

 

Adapter

ary

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.slice(0,n) and the spread operator (...).

const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
+      }

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

 

Adapter

ary

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.slice(0,n) and the spread operator (...).

const ary = (fn, n) => (...args) => fn(...args.slice(0, n));
 
const firstTwoMax = ary(Math.max, 2);
 [[2, 6, 'a'], [8, 4, 6], [10]].map(x => firstTwoMax(...x)); // [6, 8, 10]
 

call

Given a key and a set of arguments, call them when given a context. Primarily useful in composition.

Use a closure to call a stored key with stored arguments.

const call = (key, ...args) => context => context[key](...args);
@@ -123,7 +123,13 @@ Object.assig
 arrayMax([1, 2, 3]); // 3
 

unary

Creates a function that accepts up to one argument, ignoring any additional arguments.

Call the provided function, fn, with just the first argument given.

const unary = fn => val => fn(val);
 
['6', '8', '10'].map(unary(parseInt)); // [6, 8, 10]
-

Array

chunk

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.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.

const chunk = (arr, size) =>
+

Array

bifurcate

Splits values into two groups. If an element in filter is truthy, the corresponding element in the collection belongs to the first group; otherwise, it belongs to the second group.

Use Array.reduce() and Array.push() to add elements to groups, based on filter.

const bifurcate = (arr, filter) =>
+  arr.reduce((acc, val, i) => (acc[filter[i] ? 0 : 1].push(val), acc), [[], []]);
+
bifurcate(['beep', 'boop', 'foo', 'bar'], [true, true, false, true]); // [ ['beep', 'boop', 'bar'], ['foo'] ]
+

bifurcateBy

Splits values into two groups according to a predicate function, which specifies which group an element in the input collection belongs to. If the predicate function returns a truthy value, the collection element belongs to the first group; otherwise, it belongs to the second group.

Use Array.reduce() and Array.push() to add elements to groups, based on the value returned by fn for each element.

const bifurcateBy = (arr, fn) =>
+  arr.reduce((acc, val, i) => (acc[fn(val, i) ? 0 : 1].push(val), acc), [[], []]);
+
bifurcateBy(['beep', 'boop', 'foo', 'bar'], x => x[0] === 'b'); // [ ['beep', 'boop', 'bar'], ['foo'] ]
+

chunk

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.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.

const chunk = (arr, size) =>
   Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
     arr.slice(i * size, i * size + size)
   );
@@ -967,6 +973,14 @@ document.bodyShow examples
var output = '';
 times(5, i => (output += i));
 console.log(output); // 01234
+

uncurry

Uncurries a function up to depth n.

Return a variadic function. Use Array.reduce() on the provided arguments to call each subsequent curry level of the function. If the length of the provided arguments is less than n throw an error. Otherwise, call fn with the proper amount of arguments, using Array.slice(0, n). Omit the second argument, n, to uncurry up to depth 1.

const uncurry = (fn, n = 1) => (...args) => {
+  const next = acc => args => args.reduce((x, y) => x(y), acc);
+  if (n > args.length) throw new RangeError('Arguments too few!');
+  return next(fn)(args.slice(0, n));
+};
+
const add = x => y => z => x + y + z;
+const uncurriedAdd = uncurry(add, 3);
+uncurriedAdd(1, 2, 3); // 6
 

unfold

Builds an array, using an iterator function and an initial seed value.

Use a while loop and Array.push() to call the function repeatedly until it returns false. The iterator function accepts one argument (seed) and must always return an array with two elements ([value, nextSeed]) or false to terminate.

const unfold = (fn, seed) => {
   let result = [],
     val = [null, seed];
@@ -975,7 +989,9 @@ console.log<
 };
 
var f = n => (n > 50 ? false : [-n, n + 10]);
 unfold(f, 10); // [-10, -20, -30, -40, -50]
-

Math

average

Returns the average of two or more numbers.

Use Array.reduce() to add each value to an accumulator, initialized with a value of 0, divide by the length of the array.

const average = (...nums) => [...nums].reduce((acc, val) => acc + val, 0) / nums.length;
+

Math

approximatelyEqual

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 parameter, epsilon, to use a default value of 0.001.

const approximatelyEqual = (v1, v2, epsilon = 0.001) => Math.abs(v1 - v2) < epsilon;
+
approximatelyEqual(Math.PI / 2.0, 1.5708); // true
+

average

Returns the average of two or more numbers.

Use Array.reduce() to add each value to an accumulator, initialized with a value of 0, divide by the length of the array.

const average = (...nums) => [...nums].reduce((acc, val) => acc + val, 0) / nums.length;
 
average(...[1, 2, 3]); // 2
 average(1, 2, 3); // 2
 

averageBy

Returns the average of an array, after mapping each element to a value using the provided function.

Use Array.map() to map each element to the value returned by fn, Array.reduce() to add each value to an accumulator, initialized with a value of 0, divide by the length of the array.

const averageBy = (arr, fn) =>
@@ -983,9 +999,22 @@ console.log<
   arr.length;
 
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 5
 averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 5
+

binomialCoefficient

Evaluates the binomial coefficient of two integers n and k.

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.

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);
+};
+
binomialCoefficient(8, 2); // 28
 

clampNumber

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.

const clampNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b));
 
clampNumber(2, 3, 5); // 3
 clampNumber(1, -1, -5); // -1
+

degreesToRads

Converts an angle from degrees to radians.

Use Math.PI and the degree to radian formula to convert the angle from degrees to radians.

const degreesToRads = deg => deg * Math.PI / 180.0;
+
degreesToRads(90.0); // ~1.5708
 

digitize

Converts a number to an array of digits.

Convert the number to a string, using the spread operator (...) to build an array. Use Array.map() and parseInt() to transform each value to an integer.

const digitize = n => [...`${n}`].map(i => parseInt(i));
 
digitize(123); // [1, 2, 3]
 

distance

Returns the distance between two points.

Use Math.hypot() to calculate the Euclidean distance between two points.

const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0);
@@ -1109,6 +1138,8 @@ own individual rating by supplying it as the third argument.
   return arr;
 };
 
primes(10); // [2,3,5,7]
+

radsToDegrees

Converts an angle from radians to degrees.

Use Math.PI and the radian to degree formula to convert the angle from radians to degrees.

const radsToDegrees = rad => rad * 180.0 / Math.PI;
+
radsToDegrees(Math.PI / 2); // 90
 

randomIntArrayInRange

Returns an array of n random integers in the specified range.

Use Array.from() to create an empty array of the specific length, Math.random() to generate a random number and map it to the desired range, using Math.floor() to make it an integer.

const randomIntArrayInRange = (min, max, n = 1) =>
   Array.from({ length: n }, () => Math.floor(Math.random() * (max - min + 1)) + min);
 
randomIntArrayInRange(12, 35, 10); // [ 34, 14, 27, 17, 30, 27, 20, 26, 21, 14 ]
diff --git a/snippet-template.md b/snippet-template.md
index 1ee62a2f0..31cc8b26d 100644
--- a/snippet-template.md
+++ b/snippet-template.md
@@ -10,5 +10,5 @@ const functionName = arguments =>
 ```
 
 ```js
-functionName('sampleInput') // 'sampleOutput'
+functionName('sampleInput'); // 'sampleOutput'
 ```
diff --git a/snippets/approximatelyEqual.md b/snippets/approximatelyEqual.md
new file mode 100644
index 000000000..88773c163
--- /dev/null
+++ b/snippets/approximatelyEqual.md
@@ -0,0 +1,14 @@
+### approximatelyEqual
+
+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 parameter, `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
+```
diff --git a/snippets/bifurcate.md b/snippets/bifurcate.md
new file mode 100644
index 000000000..2e124711f
--- /dev/null
+++ b/snippets/bifurcate.md
@@ -0,0 +1,14 @@
+### bifurcate
+
+Splits values into two groups. If an element in `filter` is truthy, the corresponding element in the collection belongs to the first group; otherwise, it belongs to the second group.
+
+Use `Array.reduce()` and `Array.push()` to add elements to groups, based on `filter`.
+
+```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'] ]
+```
diff --git a/snippets/bifurcateBy.md b/snippets/bifurcateBy.md
new file mode 100644
index 000000000..46a00116f
--- /dev/null
+++ b/snippets/bifurcateBy.md
@@ -0,0 +1,14 @@
+### bifurcateBy
+
+Splits values into two groups according to a predicate function, which specifies which group an element in the input collection belongs to. If the predicate function returns a truthy value, the collection element belongs to the first group; otherwise, it belongs to the second group.
+
+Use `Array.reduce()` and `Array.push()` to add elements to groups, based on the value returned by `fn` for each element.
+
+```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'] ]
+```
diff --git a/snippets/binomialCoefficient.md b/snippets/binomialCoefficient.md
new file mode 100644
index 000000000..d5ff87d16
--- /dev/null
+++ b/snippets/binomialCoefficient.md
@@ -0,0 +1,26 @@
+### binomialCoefficient
+
+Evaluates the binomial coefficient of two integers `n` and `k`.
+
+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
+```
diff --git a/snippets/degreesToRads.md b/snippets/degreesToRads.md
new file mode 100644
index 000000000..ed3a2ee0e
--- /dev/null
+++ b/snippets/degreesToRads.md
@@ -0,0 +1,13 @@
+### degreesToRads
+
+Converts an angle from degrees to radians.
+
+Use `Math.PI` and the degree to radian formula to convert the angle from degrees to radians.
+
+```js
+const degreesToRads = deg => deg * Math.PI / 180.0;
+```
+
+```js
+degreesToRads(90.0); // ~1.5708
+```
diff --git a/snippets/radsToDegrees.md b/snippets/radsToDegrees.md
new file mode 100644
index 000000000..d8dd54958
--- /dev/null
+++ b/snippets/radsToDegrees.md
@@ -0,0 +1,13 @@
+### radsToDegrees
+
+Converts an angle from radians to degrees.
+
+Use `Math.PI` and the radian to degree formula to convert the angle from radians to degrees.
+
+```js
+const radsToDegrees = rad => rad * 180.0 / Math.PI;
+```
+
+```js
+radsToDegrees(Math.PI / 2); // 90
+```
diff --git a/snippets/uncurry.md b/snippets/uncurry.md
new file mode 100644
index 000000000..c5757e88d
--- /dev/null
+++ b/snippets/uncurry.md
@@ -0,0 +1,23 @@
+### uncurry
+
+Uncurries a function up to depth `n`.
+
+Return a variadic function.
+Use `Array.reduce()` on the provided arguments to call each subsequent curry level of the function.
+If the `length` of the provided arguments is less than `n` throw an error.
+Otherwise, call `fn` with the proper amount of arguments, using `Array.slice(0, n)`.
+Omit the second argument, `n`, to uncurry up to depth `1`.
+
+```js
+const uncurry = (fn, n = 1) => (...args) => {
+  const next = acc => args => args.reduce((x, y) => x(y), acc);
+  if (n > args.length) throw new RangeError('Arguments too few!');
+  return next(fn)(args.slice(0, n));
+};
+```
+
+```js
+const add = x => y => z => x + y + z;
+const uncurriedAdd = uncurry(add, 3);
+uncurriedAdd(1, 2, 3); // 6
+```
diff --git a/tag_database b/tag_database
index 5c2301db9..42fd4810a 100644
--- a/tag_database
+++ b/tag_database
@@ -3,15 +3,19 @@ allBy:array,function
 anagrams:string,recursion
 any:array
 anyBy:array,function
+approximatelyEqual:math
 arrayToHtmlList:browser,array
 ary:adapter,function
 atob:node,string,utility
 attempt:function
 average:math,array
 averageBy:math,array,function
+bifurcate:array
+bifurcateBy:array,function
 bind:function,object
 bindAll:object,function
 bindKey:function,object
+binomialCoefficient:math
 bottomVisible:browser
 btoa:node,string,utility
 byteSize:string
@@ -44,6 +48,7 @@ deepClone:object,recursion
 deepFlatten:array,recursion
 defaults:object
 defer:function
+degreesToRads:math
 delay:function
 detectDeviceType:browser
 difference:array,math
@@ -193,6 +198,7 @@ pull:array
 pullAtIndex:array
 pullAtValue:array
 pullBy:array,function,advanced
+radsToDegrees:math
 randomHexColorCode:utility,random
 randomIntArrayInRange:math,utility,random
 randomIntegerInRange:math,utility,random
@@ -258,6 +264,7 @@ transform:object,array
 truncateString:string
 truthCheckCollection:object,logic,array
 unary:adapter,function
+uncurry:function
 unescapeHTML:string,browser
 unflattenObject:object,advanced
 unfold:function,array
diff --git a/test/approximatelyEqual/approximatelyEqual.js b/test/approximatelyEqual/approximatelyEqual.js
new file mode 100644
index 000000000..85fecb15b
--- /dev/null
+++ b/test/approximatelyEqual/approximatelyEqual.js
@@ -0,0 +1,2 @@
+const approximatelyEqual = (v1, v2, epsilon = 0.001) => Math.abs(v1 - v2) < epsilon;
+module.exports = approximatelyEqual;
\ No newline at end of file
diff --git a/test/approximatelyEqual/approximatelyEqual.test.js b/test/approximatelyEqual/approximatelyEqual.test.js
new file mode 100644
index 000000000..44221aeb8
--- /dev/null
+++ b/test/approximatelyEqual/approximatelyEqual.test.js
@@ -0,0 +1,17 @@
+const test = require('tape');
+const approximatelyEqual = require('./approximatelyEqual.js');
+
+test('Testing approximatelyEqual', (t) => {
+  //For more information on all the methods supported by tape
+  //Please go to https://github.com/substack/tape
+  t.true(typeof approximatelyEqual === 'function', 'approximatelyEqual is a Function');
+  t.true(approximatelyEqual(Math.PI / 2.0 , 1.5708), 'Works for PI / 2');
+  t.true(approximatelyEqual(0.1 + 0.2, 0.3), 'Works for 0.1 + 0.2 === 0.3');
+  t.true(approximatelyEqual(0.5, 0.5), 'Works for exactly equal values');
+  t.true(approximatelyEqual(0.501, 0.5, 0.1), 'Works for a custom epsilon');
+  //t.deepEqual(approximatelyEqual(args..), 'Expected');
+  //t.equal(approximatelyEqual(args..), 'Expected');
+  //t.false(approximatelyEqual(args..), 'Expected');
+  //t.throws(approximatelyEqual(args..), 'Expected');
+  t.end();
+});
diff --git a/test/bifurcate/bifurcate.js b/test/bifurcate/bifurcate.js
new file mode 100644
index 000000000..95d7f8f50
--- /dev/null
+++ b/test/bifurcate/bifurcate.js
@@ -0,0 +1,3 @@
+const bifurcate = (arr, filter) =>
+arr.reduce((acc, val, i) => (acc[filter[i] ? 0 : 1].push(val), acc), [[], []]);
+module.exports = bifurcate;
\ No newline at end of file
diff --git a/test/bifurcate/bifurcate.test.js b/test/bifurcate/bifurcate.test.js
new file mode 100644
index 000000000..c65333ee0
--- /dev/null
+++ b/test/bifurcate/bifurcate.test.js
@@ -0,0 +1,14 @@
+const test = require('tape');
+const bifurcate = require('./bifurcate.js');
+
+test('Testing bifurcate', (t) => {
+  //For more information on all the methods supported by tape
+  //Please go to https://github.com/substack/tape
+  t.true(typeof bifurcate === 'function', 'bifurcate is a Function');
+  t.deepEqual(bifurcate([ 'beep', 'boop', 'foo', 'bar' ], [ true, true, false, true ]), [ ['beep', 'boop', 'bar'], ['foo'] ], 'Splits the collection into two groups');
+  //t.deepEqual(bifurcate(args..), 'Expected');
+  //t.equal(bifurcate(args..), 'Expected');
+  //t.false(bifurcate(args..), 'Expected');
+  //t.throws(bifurcate(args..), 'Expected');
+  t.end();
+});
diff --git a/test/bifurcateBy/bifurcateBy.js b/test/bifurcateBy/bifurcateBy.js
new file mode 100644
index 000000000..bdf04a7ce
--- /dev/null
+++ b/test/bifurcateBy/bifurcateBy.js
@@ -0,0 +1,3 @@
+const bifurcateBy = (arr, fn) =>
+arr.reduce((acc, val, i) => (acc[fn(val, i) ? 0 : 1].push(val), acc), [[], []]);
+module.exports = bifurcateBy;
\ No newline at end of file
diff --git a/test/bifurcateBy/bifurcateBy.test.js b/test/bifurcateBy/bifurcateBy.test.js
new file mode 100644
index 000000000..a6c293638
--- /dev/null
+++ b/test/bifurcateBy/bifurcateBy.test.js
@@ -0,0 +1,14 @@
+const test = require('tape');
+const bifurcateBy = require('./bifurcateBy.js');
+
+test('Testing bifurcateBy', (t) => {
+  //For more information on all the methods supported by tape
+  //Please go to https://github.com/substack/tape
+  t.true(typeof bifurcateBy === 'function', 'bifurcateBy is a Function');
+  t.deepEqual(bifurcateBy([ 'beep', 'boop', 'foo', 'bar' ], x => x[0] === 'b'), [ ['beep', 'boop', 'bar'], ['foo'] ], 'Splits the collection into two groups');
+  //t.deepEqual(bifurcateBy(args..), 'Expected');
+  //t.equal(bifurcateBy(args..), 'Expected');
+  //t.false(bifurcateBy(args..), 'Expected');
+  //t.throws(bifurcateBy(args..), 'Expected');
+  t.end();
+});
diff --git a/test/binomialCoefficient/binomialCoefficient.js b/test/binomialCoefficient/binomialCoefficient.js
new file mode 100644
index 000000000..a9808585d
--- /dev/null
+++ b/test/binomialCoefficient/binomialCoefficient.js
@@ -0,0 +1,11 @@
+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);
+};
+module.exports = binomialCoefficient;
\ No newline at end of file
diff --git a/test/binomialCoefficient/binomialCoefficient.test.js b/test/binomialCoefficient/binomialCoefficient.test.js
new file mode 100644
index 000000000..2f0e8ab20
--- /dev/null
+++ b/test/binomialCoefficient/binomialCoefficient.test.js
@@ -0,0 +1,18 @@
+const test = require('tape');
+const binomialCoefficient = require('./binomialCoefficient.js');
+
+test('Testing binomialCoefficient', (t) => {
+  //For more information on all the methods supported by tape
+  //Please go to https://github.com/substack/tape
+  t.true(typeof binomialCoefficient === 'function', 'binomialCoefficient is a Function');
+  t.equal(binomialCoefficient(8, 2), 28, 'Returns the appropriate value');
+  t.equal(binomialCoefficient(0, 0), 1, 'Returns the appropriate value');
+  t.equal(binomialCoefficient(5, 3), 10, 'Returns the appropriate value');
+  t.true(Number.isNaN(binomialCoefficient(NaN, 3)), 'Returns NaN');
+  t.true(Number.isNaN(binomialCoefficient(5, NaN)), 'Returns NaN');
+  //t.deepEqual(binomialCoefficient(args..), 'Expected');
+  //t.equal(binomialCoefficient(args..), 'Expected');
+  //t.false(binomialCoefficient(args..), 'Expected');
+  //t.throws(binomialCoefficient(args..), 'Expected');
+  t.end();
+});
diff --git a/test/degreesToRads/degreesToRads.js b/test/degreesToRads/degreesToRads.js
new file mode 100644
index 000000000..da6d51836
--- /dev/null
+++ b/test/degreesToRads/degreesToRads.js
@@ -0,0 +1,2 @@
+const degreesToRads = deg => deg * Math.PI / 180.0;
+module.exports = degreesToRads;
\ No newline at end of file
diff --git a/test/degreesToRads/degreesToRads.test.js b/test/degreesToRads/degreesToRads.test.js
new file mode 100644
index 000000000..8ec980a10
--- /dev/null
+++ b/test/degreesToRads/degreesToRads.test.js
@@ -0,0 +1,15 @@
+const test = require('tape');
+const degreesToRads = require('./degreesToRads.js');
+
+test('Testing degreesToRads', (t) => {
+  //For more information on all the methods supported by tape
+  //Please go to https://github.com/substack/tape
+  const approxeq = (v1,v2, diff = 0.001) => Math.abs(v1 - v2) < diff; // Use to account for rounding errors
+  t.true(typeof degreesToRads === 'function', 'degreesToRads is a Function');
+  t.true(approxeq(degreesToRads(90.0), Math.PI / 2), 'Returns the appropriate value');
+  //t.deepEqual(degreesToRads(args..), 'Expected');
+  //t.equal(degreesToRads(args..), 'Expected');
+  //t.false(degreesToRads(args..), 'Expected');
+  //t.throws(degreesToRads(args..), 'Expected');
+  t.end();
+});
diff --git a/test/radsToDegrees/radsToDegrees.js b/test/radsToDegrees/radsToDegrees.js
new file mode 100644
index 000000000..d9a370b78
--- /dev/null
+++ b/test/radsToDegrees/radsToDegrees.js
@@ -0,0 +1,2 @@
+const radsToDegrees = rad => rad * 180.0 / Math.PI;
+module.exports = radsToDegrees;
\ No newline at end of file
diff --git a/test/radsToDegrees/radsToDegrees.test.js b/test/radsToDegrees/radsToDegrees.test.js
new file mode 100644
index 000000000..446485d76
--- /dev/null
+++ b/test/radsToDegrees/radsToDegrees.test.js
@@ -0,0 +1,14 @@
+const test = require('tape');
+const radsToDegrees = require('./radsToDegrees.js');
+
+test('Testing radsToDegrees', (t) => {
+  //For more information on all the methods supported by tape
+  //Please go to https://github.com/substack/tape
+  t.true(typeof radsToDegrees === 'function', 'radsToDegrees is a Function');
+  t.equal(radsToDegrees(Math.PI / 2), 90, 'Returns the appropriate value');
+  //t.deepEqual(radsToDegrees(args..), 'Expected');
+  //t.equal(radsToDegrees(args..), 'Expected');
+  //t.false(radsToDegrees(args..), 'Expected');
+  //t.throws(radsToDegrees(args..), 'Expected');
+  t.end();
+});
diff --git a/test/testlog b/test/testlog
index 871c6bb41..8b77ecac0 100644
--- a/test/testlog
+++ b/test/testlog
@@ -1,9 +1,11 @@
 Test log for: Wed Feb 14 2018 11:45:44 GMT+0200 (GTB Standard Time)
+Test log for: Wed Feb 14 2018 12:46:59 GMT+0200 (GTB Standard Time)
 
 > 30-seconds-of-code@0.0.1 test G:\My Files\git Repositories\30-seconds-of-code
 > tape test/**/*.test.js | tap-spec
 
 
+
   Testing all
 
     √ all is a Function
@@ -39,6 +41,21 @@ Test log for: Wed Feb 14 2018 11:45:44 GMT+0200 (GTB Standard Time)
     √ anyBy is a Function
     √ Returns true with predicate function
     √ Returns false with a predicate function
+    
+  Testing anagrams
+
+    √ anagrams is a Function
+    √ Generates all anagrams of a string
+    √ Works for single-letter strings
+    √ Works for empty strings
+
+  Testing approximatelyEqual
+
+    √ approximatelyEqual is a Function
+    √ Works for PI / 2
+    √ Works for 0.1 + 0.2 === 0.3
+    √ Works for exactly equal values
+    √ Works for a custom epsilon
 
   Testing arrayToHtmlList
 
@@ -82,6 +99,16 @@ Test log for: Wed Feb 14 2018 11:45:44 GMT+0200 (GTB Standard Time)
     √ Produces the right result with a function
     √ Produces the right result with a property name
 
+  Testing bifurcate
+
+    √ bifurcate is a Function
+    √ Splits the collection into two groups
+
+  Testing bifurcateBy
+
+    √ bifurcateBy is a Function
+    √ Splits the collection into two groups
+
   Testing binarySearch
 
     √ binarySearch is a Function
@@ -105,6 +132,15 @@ Test log for: Wed Feb 14 2018 11:45:44 GMT+0200 (GTB Standard Time)
     √ bindKey is a Function
     √ Binds function to an object context
 
+  Testing binomialCoefficient
+
+    √ binomialCoefficient is a Function
+    √ Returns the appropriate value
+    √ Returns the appropriate value
+    √ Returns the appropriate value
+    √ Returns NaN
+    √ Returns NaN
+
   Testing bottomVisible
 
     √ bottomVisible is a Function
@@ -297,6 +333,11 @@ Test log for: Wed Feb 14 2018 11:45:44 GMT+0200 (GTB Standard Time)
 
     √ defer is a Function
 
+  Testing degreesToRads
+
+    √ degreesToRads is a Function
+    √ Returns the appropriate value
+
   Testing delay
 
     √ delay is a Function
@@ -1252,6 +1293,11 @@ Test log for: Wed Feb 14 2018 11:45:44 GMT+0200 (GTB Standard Time)
     √ quickSort(undefined) throws an error
     √ quickSort([11, 1, 324, 23232, -1, 53, 2, 524, 32, 13, 156, 133, 62, 12, 4]) takes less than 2s to run
 
+  Testing radsToDegrees
+
+    √ radsToDegrees is a Function
+    √ Returns the appropriate value
+
   Testing randomHexColorCode
 
     √ randomHexColorCode is a Function
@@ -1655,6 +1701,13 @@ Test log for: Wed Feb 14 2018 11:45:44 GMT+0200 (GTB Standard Time)
     √ unary is a Function
     √ Discards arguments after the first one
 
+  Testing uncurry
+
+    √ uncurry is a Function
+    √ Works without a provided value for n
+    √ Works without n = 2
+    √ Works withoutn = 3
+
   Testing unescapeHTML
 
     √ unescapeHTML is a Function
@@ -1839,6 +1892,8 @@ Test log for: Wed Feb 14 2018 11:45:44 GMT+0200 (GTB Standard Time)
     √ zipWith is a Function
     √ Runs the function provided
     √ Sends a GET request
+    √ Sends a GET request
+    √ Runs the function provided
     √ Runs promises in series
     √ Sends a POST request
     √ Works with multiple promises
@@ -1846,6 +1901,6 @@ Test log for: Wed Feb 14 2018 11:45:44 GMT+0200 (GTB Standard Time)
 
   total:     924
   passing:   924
-  duration:  2.4s
+  duration:  2.5s
 
 
diff --git a/test/uncurry/uncurry.js b/test/uncurry/uncurry.js
new file mode 100644
index 000000000..a926982d5
--- /dev/null
+++ b/test/uncurry/uncurry.js
@@ -0,0 +1,6 @@
+const uncurry = (fn, n = 1) => (...args) => {
+const next = acc => args => args.reduce((x, y) => x(y), acc);
+if (n > args.length) throw new RangeError('Arguments too few!');
+return next(fn)(args.slice(0, n));
+};
+module.exports = uncurry;
\ No newline at end of file
diff --git a/test/uncurry/uncurry.test.js b/test/uncurry/uncurry.test.js
new file mode 100644
index 000000000..76ef507fa
--- /dev/null
+++ b/test/uncurry/uncurry.test.js
@@ -0,0 +1,20 @@
+const test = require('tape');
+const uncurry = require('./uncurry.js');
+
+test('Testing uncurry', (t) => {
+  //For more information on all the methods supported by tape
+  //Please go to https://github.com/substack/tape
+  t.true(typeof uncurry === 'function', 'uncurry is a Function');
+  const add = x => y => z => x + y + z;
+  const add1 = uncurry(add);
+  const add2 = uncurry(add, 2);
+  const add3 = uncurry(add, 3);
+  t.equal(add1(1)(2)(3), 6, 'Works without a provided value for n');
+  t.equal(add2(1,2)(3), 6, 'Works without n = 2');
+  t.equal(add3(1,2,3), 6, 'Works withoutn = 3');
+  //t.deepEqual(uncurry(args..), 'Expected');
+  //t.equal(uncurry(args..), 'Expected');
+  //t.false(uncurry(args..), 'Expected');
+  //t.throws(uncurry(args..), 'Expected');
+  t.end();
+});