Merge pull request #478 from Chalarangelo/update-memoize

Update memoize
This commit is contained in:
Angelos Chalaris
2018-01-03 17:03:38 +02:00
committed by GitHub
3 changed files with 156 additions and 40 deletions

172
README.md
View File

@ -229,7 +229,9 @@ average(1, 2, 3);
* [`isEven`](#iseven)
* [`isPrime`](#isprime)
* [`lcm`](#lcm)
* [`maxN`](#maxn)
* [`median`](#median)
* [`minN`](#minn)
* [`percentile`](#percentile)
* [`powerset`](#powerset)
* [`primes`](#primes)
@ -340,19 +342,29 @@ average(1, 2, 3);
</details>
### _Uncategorized_
<details>
<summary>View contents</summary>
* [`maxN`](#maxn)
* [`minN`](#minn)
</details>
---
## 🔌 Adapter
### 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.
### 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.
```js
const call = (key, ...args) => context => context[key](...args);
```
```
<details>
<summary>Examples</summary>
@ -364,23 +376,23 @@ const map = call.bind(null, 'map');
Promise.resolve([1, 2, 3])
.then(map(x => 2 * x))
.then(console.log); //[ 2, 4, 6 ]
```
```
</details>
<br>[⬆ Back to top](#table-of-contents)
### collectInto
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.
### collectInto
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);
```
```
<details>
<summary>Examples</summary>
@ -390,23 +402,23 @@ 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);
```
```
</details>
<br>[⬆ Back to top](#table-of-contents)
### flip
Flip takes a function as an argument, then makes the first argument the last
Return a closure that takes variadic inputs, and splices the last argument to make it the first argument before applying the rest.
### flip
Flip takes a function as an argument, then makes the first argument the last
Return a closure that takes variadic inputs, and splices the last argument to make it the first argument before applying the rest.
```js
const flip = fn => (...args) => fn(args.pop(), ...args);
```
```
<details>
<summary>Examples</summary>
@ -418,7 +430,7 @@ let mergePerson = mergeFrom.bind(null, a);
mergePerson(b); // == b
b = {};
Object.assign(b, a); // == b
```
```
</details>
@ -480,16 +492,16 @@ delay(2000).then(() => console.log('Hi!')); // // Promise resolves after 2s
<br>[⬆ Back to top](#table-of-contents)
### spreadOver
Takes a variadic function and returns a closure that accepts an array of arguments to map to the inputs of the function.
Use closures and the spread operator (`...`) to map the array of arguments to the inputs of the function.
### spreadOver
Takes a variadic function and returns a closure that accepts an array of arguments to map to the inputs of the function.
Use closures and the spread operator (`...`) to map the array of arguments to the inputs of the function.
```js
const spreadOver = fn => argsArr => fn(...argsArr);
```
```
<details>
<summary>Examples</summary>
@ -497,7 +509,7 @@ const spreadOver = fn => argsArr => fn(...argsArr);
const arrayMax = spreadOver(Math.max);
arrayMax([1, 2, 3]); // 3
arrayMax([1, 2, 4]); // 4
```
```
</details>
@ -3271,6 +3283,31 @@ lcm([1, 3, 4], 5); // 60
<br>[⬆ Back to top](#table-of-contents)
### maxN
Returns the `n` maximum elements from the provided array. If `n` is greater than or equal to the provided array's length than return the original array(sorted in descending order).
Sort's the array's shallow copy in descending order and returns the first n elements
Skip the second argument to get a single element(in the form of a array)
```js
const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n);
```
<details>
<summary>Examples</summary>
```js
maxN([1, 2, 3]); // [3]
maxN([1, 2, 3], 2); // [3,2]
maxN([1, 2, 3], 4); // [3,2,1]
```
</details>
<br>[⬆ Back to top](#table-of-contents)
### median
Returns the median of an array of numbers.
@ -3299,6 +3336,30 @@ median([0, 10, -2, 7]); // 3.5
<br>[⬆ Back to top](#table-of-contents)
### minN
Returns the `n` minimum elements from the provided array. If `n` is greater than or equal to the provided array's length than return the original array(sorted in ascending order).
Sort's the array's shallow copy in ascending order and returns the first n elements
Skip the second argument to get a single element(in the form of a array)
```js
const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n);
```
<details>
<summary>Examples</summary>
```js
minN([1, 2, 3]); // [1]
minN([1, 2, 3], 2); // [1,2]
minN([1, 2, 3], 4); // [1,2,3]
```
</details>
<br>[⬆ Back to top](#table-of-contents)
### percentile
Uses the percentile formula to calculate how many numbers in the given array are less or equal to the given value.
@ -5349,6 +5410,45 @@ yesNo('Foo', true); // true
<br>[⬆ Back to top](#table-of-contents)
### maxN
Returns the `n` maximum elements from the provided array. If `n` is greater than or equal to the provided array's length than return the original array(sorted in descending order).
Sort's the array's shallow copy in descending order and returns the first n elements
Skip the second argument to get a single element(in the form of a array)
```js
const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n);
```
```js
maxN([1, 2, 3]); // [3]
maxN([1, 2, 3], 2); // [3,2]
maxN([1, 2, 3], 4); // [3,2,1]
```
<br>[⬆ back to top](#table-of-contents)
### minN
Returns the `n` minimum elements from the provided array. If `n` is greater than or equal to the provided array's length than return the original array(sorted in ascending order).
Sort's the array's shallow copy in ascending order and returns the first n elements
Skip the second argument to get a single element(in the form of a array)
```js
const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n);
```
```js
minN([1, 2, 3]); // [1]
minN([1, 2, 3], 2); // [1,2]
minN([1, 2, 3], 4); // [1,2,3]
```
<br>[⬆ back to top](#table-of-contents)
## Collaborators
| [<img src="https://github.com/Chalarangelo.png" width="100px;"/>](https://github.com/Chalarangelo)<br/> [<sub>Angelos Chalaris</sub>](https://github.com/Chalarangelo) | [<img src="https://github.com/Pl4gue.png" width="100px;"/>](https://github.com/Pl4gue)<br/> [<sub>David Wu</sub>](https://github.com/Pl4gue) | [<img src="https://github.com/fejes713.png" width="100px;"/>](https://github.com/fejes713)<br/> [<sub>Stefan Feješ</sub>](https://github.com/fejes713) | [<img src="https://github.com/kingdavidmartins.png" width="100px;"/>](https://github.com/kingdavidmartins)<br/> [<sub>King David Martins</sub>](https://github.com/iamsoorena) | [<img src="https://github.com/iamsoorena.png" width="100px;"/>](https://github.com/iamsoorena)<br/> [<sub>Soorena Soleimani</sub>](https://github.com/iamsoorena) |

View File

@ -717,6 +717,10 @@ isPrime(12); // false
};
</code></pre><pre><code class="language-js">lcm(12, 7); // 84
lcm([1, 3, 4], 5); // 60
</code></pre></div></div><br/><div class="card fluid"><div class="section double-padded"><h3 id="maxn">maxN</h3></div><div class="section double-padded"><p>Returns the <code>n</code> maximum elements from the provided array. If <code>n</code> is greater than or equal to the provided array's length than return the original array(sorted in descending order).</p><p>Sort's the array's shallow copy in descending order and returns the first n elements</p><p>Skip the second argument to get a single element(in the form of a array)</p><pre><code class="language-js">const maxN = (arr, n = 1) =&gt; [...arr].sort((a, b) =&gt; b - a).slice(0, n);
</code></pre><pre><code class="language-js">maxN([1, 2, 3]); // [3]
maxN([1, 2, 3], 2); // [3,2]
maxN([1, 2, 3], 4); // [3,2,1]
</code></pre></div></div><br/><div class="card fluid"><div class="section double-padded"><h3 id="median">median</h3></div><div class="section double-padded"><p>Returns the median of an array of numbers.</p><p>Find the middle of the array, use <code>Array.sort()</code> to sort the values. Return the number at the midpoint if <code>length</code> is odd, otherwise the average of the two middle numbers.</p><pre><code class="language-js">const median = arr =&gt; {
const mid = Math.floor(arr.length / 2),
nums = [...arr].sort((a, b) =&gt; a - b);
@ -724,6 +728,10 @@ lcm([1, 3, 4], 5); // 60
};
</code></pre><pre><code class="language-js">median([5, 6, 50, 1, -5]); // 5
median([0, 10, -2, 7]); // 3.5
</code></pre></div></div><br/><div class="card fluid"><div class="section double-padded"><h3 id="minn">minN</h3></div><div class="section double-padded"><p>Returns the <code>n</code> minimum elements from the provided array. If <code>n</code> is greater than or equal to the provided array's length than return the original array(sorted in ascending order).</p><p>Sort's the array's shallow copy in ascending order and returns the first n elements</p><p>Skip the second argument to get a single element(in the form of a array)</p><pre><code class="language-js">const minN = (arr, n = 1) =&gt; [...arr].sort((a, b) =&gt; a - b).slice(0, n);
</code></pre><pre><code class="language-js">minN([1, 2, 3]); // [1]
minN([1, 2, 3], 2); // [1,2]
minN([1, 2, 3], 4); // [1,2,3]
</code></pre></div></div><br/><div class="card fluid"><div class="section double-padded"><h3 id="percentile">percentile</h3></div><div class="section double-padded"><p>Uses the percentile formula to calculate how many numbers in the given array are less or equal to the given value.</p><p>Use <code>Array.reduce()</code> to calculate how many numbers are below the value and how many are the same value and apply the percentile formula.</p><pre><code class="language-js">const percentile = (arr, val) =&gt;
100 * arr.reduce((acc, v) =&gt; acc + (v &lt; val ? 1 : 0) + (v === val ? 0.5 : 0), 0) / arr.length;
</code></pre><pre><code class="language-js">percentile([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 6); // 55

View File

@ -2,13 +2,20 @@
Returns the memoized (cached) function.
Use `Object.create(null)` to create an empty object without `Object.prototype` (so that those properties are not resolved if the input value is something like `'hasOwnProperty'`).
Return a function which takes a single argument to be supplied to the memoized function by first checking if the function's output for that specific input value is already cached, or store and return it if not.
Create an empty cache by instantiating a new `Map` object.
Return a function which takes a single argument to be supplied to the memoized function by first checking if the function's output for that specific input value is already cached, or store and return it if not. The `function` keyword must be used in order to allow the memoized function to have its `this` context changed if necessary.
Allow access to the `cache` by setting it as a property on the returned function.
```js
const memoize = fn => {
const cache = Object.create(null);
return value => cache[value] || (cache[value] = fn(value));
const cache = new Map();
const cached = function(val) {
return cache.has(val)
? cache.get(val)
: cache.set(val, fn.call(this, val)) && cache.get(val);
};
cached.cache = cache;
return cached;
};
```
@ -17,4 +24,5 @@ const memoize = fn => {
const anagramsCached = memoize(anagrams);
anagramsCached('javascript'); // takes a long time
anagramsCached('javascript'); // returns virtually instantly since it's now cached
console.log(anagramsCached.cache); // Map
```