-
Notifications
You must be signed in to change notification settings - Fork 87
/
evolve.js
62 lines (52 loc) · 1.29 KB
/
evolve.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
import {_isArray} from './_internals/_isArray'
import {mapArray, mapObject} from './map'
import {type} from './type'
export function evolveArray(rules, list) {
return mapArray(
(x, i) => {
if (type(rules[i]) === 'Function') {
return rules[i](x)
}
return x
},
list,
true
)
}
export function evolveObject(rules, iterable) {
return mapObject((x, prop) => {
if (type(x) === 'Object') {
const typeRule = type(rules[prop])
if (typeRule === 'Function') {
return rules[prop](x)
}
if (typeRule === 'Object') {
return evolve(rules[prop], x)
}
return x
}
if (type(rules[prop]) === 'Function') {
return rules[prop](x)
}
return x
}, iterable)
}
export function evolve(rules, iterable) {
if (arguments.length === 1) {
return _iterable => evolve(rules, _iterable)
}
const rulesType = type(rules)
const iterableType = type(iterable)
if (iterableType !== rulesType) {
throw new Error('iterableType !== rulesType')
}
if (!['Object', 'Array'].includes(rulesType)) {
throw new Error(
`'iterable' and 'rules' are from wrong type ${rulesType}`
)
}
if (iterableType === 'Object') {
return evolveObject(rules, iterable)
}
return evolveArray(rules, iterable)
}