-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6af4228
commit 64c9320
Showing
15 changed files
with
452 additions
and
5 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { basicAsync } from './basic-ingredients-async'; | ||
import { aggregateRecipe } from '../recipes'; | ||
|
||
export const aggregateAsync = aggregateRecipe(basicAsync); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { AnyIterable } from 'augmentative-iterable'; | ||
import { AverageStepper } from '../types'; | ||
import { getAverageStepper } from '../utils'; | ||
import { BasicIngredients } from './ingredients'; | ||
import { v4 as uuidV4 } from 'uuid'; | ||
|
||
const baseDefaultId = uuidV4(); | ||
const contextSymbol = Symbol('context'); | ||
|
||
class Aggregations { | ||
[contextSymbol]: any = { | ||
id: 0, | ||
defaultId(): string | number { | ||
return `${baseDefaultId}${this.id++}`; | ||
}, | ||
}; | ||
|
||
sum(value: number, id: string | number = this[contextSymbol].defaultId()) { | ||
const context = (this[contextSymbol].sum ??= {}); | ||
return (context[id] = (context[id] ?? 0) + value); | ||
} | ||
multiply( | ||
value: number, | ||
id: string | number = this[contextSymbol].defaultId(), | ||
) { | ||
const context = (this[contextSymbol].multiply ??= {}); | ||
return (context[id] = (context[id] ?? 1) * value); | ||
} | ||
max( | ||
value: string | number, | ||
id: string | number = this[contextSymbol].defaultId(), | ||
) { | ||
const context = (this[contextSymbol].max ??= {}); | ||
if (context[id] === undefined || context[id] < value) context[id] = value; | ||
return context[id]; | ||
} | ||
avg(value: number, id: string | number = this[contextSymbol].defaultId()) { | ||
const context = (this[contextSymbol].avg ??= {}); | ||
if (context[id] === undefined) context[id] = getAverageStepper(); | ||
const stepper: AverageStepper = context[id]; | ||
stepper.step(value); | ||
return stepper.avg; | ||
} | ||
min<T>(value: T, id: string | number = this[contextSymbol].defaultId()) { | ||
const context = (this[contextSymbol].min ??= {}); | ||
if (context[id] === undefined || context[id] > value) context[id] = value; | ||
return context[id]; | ||
} | ||
first<T>(value: T, id: string | number = this[contextSymbol].defaultId()) { | ||
const context = (this[contextSymbol].first ??= {}); | ||
if (context[id] === undefined) context[id] = { value }; | ||
return context[id].value; | ||
} | ||
last<T>(value: T) { | ||
return value; | ||
} | ||
modSum( | ||
value: number, | ||
mod: number, | ||
id: string | number = this[contextSymbol].defaultId(), | ||
) { | ||
const context = (this[contextSymbol].modSum ??= {}); | ||
return (context[id] = this.sum(value, `modSum${baseDefaultId}${id}`) % mod); | ||
} | ||
modMultiply( | ||
value: number, | ||
mod: number, | ||
id: string | number = this[contextSymbol].defaultId(), | ||
) { | ||
const context = (this[contextSymbol].modMultiply ??= {}); | ||
return (context[id] = | ||
this.multiply(value, `modMultiply${baseDefaultId}${id}`) % mod); | ||
} | ||
} | ||
|
||
export function aggregateRecipe(ingredients: BasicIngredients): any { | ||
const { forEach, resolver } = ingredients; | ||
return function aggregate<T>( | ||
this: AnyIterable<T>, | ||
callback: (a: T, agg: Aggregations, prev: any) => any, | ||
result?: any, | ||
) { | ||
const agg = new Aggregations(); | ||
return resolver( | ||
forEach.call(this, (item: T) => { | ||
agg[contextSymbol].id = 0; | ||
result = callback(item, agg, result); | ||
}), | ||
() => result, | ||
); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { basic } from './basic-ingredients'; | ||
import { aggregateRecipe } from '../recipes'; | ||
|
||
export const aggregate = aggregateRecipe(basic); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './aggregate'; | ||
export * from './all'; | ||
export * from './any'; | ||
export * from './append'; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
export interface Aggregations { | ||
sum(value: number, id?: string | number): number; | ||
multiply(value: number, id?: string | number): number; | ||
max<T extends string | number>(value: T, id?: string | number): T; | ||
avg(value: number, id?: string | number): number; | ||
min<T>(value: T, id?: string | number): T; | ||
first<T>(value: T, id?: string | number): T; | ||
last<T>(value: T, id?: string | number): T; | ||
modSum(value: number, mod: number, id?: string | number): number; | ||
modMultiply(value: number, mod: number, id?: string | number): number; | ||
} | ||
|
||
export interface AggregateFunction<T> { | ||
/** | ||
* Execute aggregations, returning the last result. This is a resolving operation | ||
* The aggregations available are: sum, multiply, max, avg, min, first, last, modSum, modMultiply | ||
* @param callback The callback to execute the aggregations. It receives a second param: an object containing all the available aggregations | ||
* @returns the last method result | ||
*/ | ||
<R, I extends R | undefined = R | undefined>( | ||
callback: (item: T, agg: Aggregations, acc: I) => R, | ||
initialize?: I, | ||
): R; | ||
} | ||
export interface AsyncAggregateFunction<T> { | ||
/** | ||
* Execute aggregations, returning the last result. This is a resolving operation | ||
* The aggregations available are: sum, multiply, max, avg, min, first, last, modSum, modMultiply | ||
* @param callback The callback to execute the aggregations. It receives a second param: an object containing all the available aggregations | ||
* @returns the last method result | ||
*/ | ||
<R, I extends R | undefined = R | undefined>( | ||
callback: (item: T, agg: Aggregations, acc: R | undefined) => R, | ||
initialize?: I, | ||
): Promise<R>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.