-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathgenericReduce.js
79 lines (76 loc) · 2.61 KB
/
genericReduce.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
const isArray = require('./isArray')
const objectValues = require('./objectValues')
const isGeneratorFunction = require('./isGeneratorFunction')
const isAsyncGeneratorFunction = require('./isAsyncGeneratorFunction')
const iteratorReduce = require('./iteratorReduce')
const asyncIteratorReduce = require('./asyncIteratorReduce')
const symbolIterator = require('./symbolIterator')
const symbolAsyncIterator = require('./symbolAsyncIterator')
const __ = require('./placeholder')
const curry2 = require('./curry2')
const curryArgs3 = require('./curryArgs3')
const arrayReduce = require('./arrayReduce')
const objectReduce = require('./objectReduce')
const mapReduce = require('./mapReduce')
const reducerConcat = require('./reducerConcat')
/**
* @name genericReduce
*
* @synopsis
* ```coffeescript [specscript]
* Foldable<T> = Iterable<T>|AsyncIterable<T>
* |{ reduce: (any, T)=>any }|Object<T>
*
* genericReduce<T>(
* collection Foldable<T>,
* reducer (any, T)=>any,
* result any?,
* ) -> result
* ```
*
* @related genericReduceConcurrent
*
* @TODO genericReduceSync(collection, reducer, init) - performance optimization for some of these genericReduces that we know are synchronous
*
* @TODO genericReducePool(poolSize, collection, reducer, init) - for some of these genericReduces that we want to race - result should not care about order of concatenations
* reduce.pool
* transform.pool
* flatMap.pool
*/
const genericReduce = function (collection, reducer, result) {
if (isArray(collection)) {
return arrayReduce(collection, reducer, result)
}
if (collection == null) {
return result === undefined
? curry2(reducer, collection, __)
: reducer(result, collection)
}
if (collection.constructor == Map) {
return mapReduce(collection, reducer, result)
}
if (typeof collection[symbolIterator] == 'function') {
return iteratorReduce(
collection[symbolIterator](), reducer, result)
}
if (typeof collection[symbolAsyncIterator] == 'function') {
return asyncIteratorReduce(
collection[symbolAsyncIterator](), reducer, result)
}
if (typeof collection.reduce == 'function') {
return collection.reduce(reducer, result)
}
if (typeof collection.chain == 'function') {
return collection.chain(curry2(reducer, result, __))
}
if (typeof collection.flatMap == 'function') {
return collection.flatMap(curry2(reducer, result, __))
}
if (collection.constructor == Object) {
return objectReduce(collection, reducer, result)
}
return result === undefined
? curry2(reducer, collection, __)
: reducer(result, collection)
}
module.exports = genericReduce