/
aggregate.ts
75 lines (69 loc) · 2.54 KB
/
aggregate.ts
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
/*
* @author electricessence / https://github.com/electricessence/
* @license MIT
*/
import ArgumentNullException from '@tsdotnet/exceptions/dist/ArgumentNullException';
import InvalidOperationException from '@tsdotnet/exceptions/dist/InvalidOperationException';
import {IterableTransform} from '../IterableTransform';
/**
* An iterable transform that applies an accumulator function over a sequence.
* The first entry is used as the initial accumulator value, and the specified function is used to select the result value.
* @param {(previous: (T | undefined), current: T, index: number) => T} reducer
* @return {IterableTransform<T, T | undefined>}
*/
export default function aggregate<T> (
reducer: (
previous: T,
current: T,
index: number) => T): IterableTransform<T, T>;
/**
* An iterable transform that applies an accumulator function over a sequence.
* The specified seed value is used as the initial accumulator value, and the specified function is used to select the result value.
* @param {(previous: U, current: T, index: number) => U} reducer
* @param {U} initialValue
* @return {IterableTransform<T, U>}
*/
export default function aggregate<T, U> (
reducer: (
previous: U,
current: T,
index: number) => U,
initialValue: U): IterableTransform<T, U>;
/**
* An iterable transform that applies an accumulator function over a sequence.
* The specified `initialValue` is used as the initial accumulator value, and the specified function is used to select the result value.
* If no `initialValue` is specified, the first entry in the sequence is used.
* @param {(previous: (U | undefined), current: T, index: number) => U} reducer
* @param {U} initialValue
* @return {IterableTransform<T, U | undefined>}
*/
export default function aggregate<T, U> (
reducer: (
previous: U,
current: T,
index: number) => U,
initialValue?: U
): IterableTransform<T, U | undefined> {
return function(sequence: Iterable<T>): U | undefined {
if(!sequence) throw new ArgumentNullException('sequence');
let i = 0;
if(initialValue===undefined)
{
const iterator = sequence[Symbol.iterator]();
let n = iterator.next();
if(n.done) throw new InvalidOperationException('Sequence is empty. Specify an initial value allow for an empty iterable.');
let previous: any = n.value;
while(!(n = iterator.next()).done)
{
previous = reducer(previous, n.value, ++i);
}
return previous;
}
else
{
let previous: any = initialValue;
for(const current of sequence) previous = reducer(previous, current, i++);
return previous;
}
};
}