-
Notifications
You must be signed in to change notification settings - Fork 1
/
functional.js
85 lines (64 loc) · 2.18 KB
/
functional.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
const curry = fn => (...args) => fn.bind(null, ...args);
const map = curry((fn, arr) => arr.map(fn));
const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
const asyncCompose = (...fns) => x => fns.reduceRight((y, fn) => y.then(fn), Promise.resolve(x));
/**
* @param {...Function} fns List of functions to pipe in order first to last
* @returns {Function} Function that passes input through all piped functions
*/
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
/** TEST
describe('pipe()', () => {
const double = jest.fn((x) => x * 2);
const orderBurger = utils.pipe(double, double);
it('returns a function', () => {
expect(typeof orderBurger).toBe('function');
});
it('calls each input function', () => {
const input = 1;
orderBurger(input);
expect(double).toBeCalledWith(input);
expect(double).toBeCalledWith(2 * input);
});
it('returns the accumulation of each input function', () => {
const patties = orderBurger(1);
expect(patties).toBe(4);
});
});
*/
const asyncPipe = (...fns) => x => fns.reduce((y, fn) => y.then(fn), Promise.resolve(x))
const trace = curry((label, x) => {
console.log(`== ${ label }: ${ x }`);
return x;
});
const tap = curry((fn, x) => {
fn(x);
return x;
});
/**
* Calls a function with args only when the predicate is true. Otherwise, returns initial args.
*
* @param {boolean | Function} predicate
* @param {Function} callback
* @returns {Function}
*/
const when = (predicate, callback) => (args) => {
const shoudRun = predicate instanceof Function ? predicate(args) : predicate;
return shoudRun ? callback(args) : args;
};
const map = fn => initialValue => initialValue.map(fn)
const keys = Object.keys
const sort = (fn, items = []) => items.sort(fn)
const forEach = (fn, items) => items.forEach(fn)
const filterNullishEntries = arr => arr.filter(([key, val]) => val != null)
const filterNullishObject = pipe(
Object.entries,
filterNullishEntries,
Object.fromEntries
)
const keepEntriesByKey = keys => arr => {
return arr.filter(([key, val]) => keys.includes(key))
}
const pluckObjectKeys = keys => {
return pipe(Object.entries, keepEntriesByKey(keys), Object.fromEntries)
}