Skip to content

Instantly share code, notes, and snippets.

@mattpodwysocki
Created April 2, 2020 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattpodwysocki/539756349ed14dfa4ead5e97d72867c2 to your computer and use it in GitHub Desktop.
Save mattpodwysocki/539756349ed14dfa4ead5e97d72867c2 to your computer and use it in GitHub Desktop.
import { identityAsync } from '../util/identity';
import { wrapWithAbort } from './operators/withabort';
import { throwIfAborted } from '../aborterror';
/**
* The options for calculating an average.
*
* @export
* @interface AverageOptions
* @template T The type of elements in the source sequence.
*/
export interface AverageOptions<T> {
/**
* An optional selector used to get the value to average.
*
* @memberof AverageOptions
*/
selector?: (x: T, signal?: AbortSignal) => number | Promise<number>;
/**
* An optional thisArg for the selector.
*
* @type {*}
* @memberof AverageOptions
*/
thisArg?: any;
/**
* An optional abort signal to cancel the operation at any time.
*
* @type {AbortSignal}
* @memberof AverageOptions
*/
signal?: AbortSignal;
}
/**
* Computes the average of the async-iterable sequence.
*
* @export
* @param {AsyncIterable<number>} source The source async-iterable sequence to compute the average.
* @returns {Promise<number>} A Promise which returns the computed average for the async-iterable sequence.
*/
export async function average(
source: AsyncIterable<number>,
options?: AverageOptions<number>
): Promise<number>;
/**
* Computes the average of the async-iterable sequence.
*
* @export
* @template TSource The type of elements in the source sequence.
* @param {AsyncIterable<TSource>} source source async-iterable sequence to compute the average.
* @param {((x: TSource, signal?: AbortSignal) => number | Promise<number>)} [selector] An optional selector used to get the value to average.
* @param {*} [thisArg] An optional thisArg for the selector.
* @param {AbortSignal} [signal] An optional abort signal to cancel the operation at any time.
* @returns {Promise<number>} A Promise which returns the computed average for the async-iterable sequence.
*/
export async function average<TSource>(
source: AsyncIterable<TSource>,
options?: AverageOptions<TSource>
): Promise<number>;
/**
* Computes the average of the async-iterable sequence.
*
* @export
* @param {AsyncIterable<any>} source source async-iterable sequence to compute the average.
* @param {((x: any, signal?: AbortSignal) => number | Promise<number>)} [selector=identityAsync] An optional selector used to get the value
* to average.
* @param {*} [thisArg] An optional thisArg for the selector.
* @param {AbortSignal} [signal] An optional abort signal to cancel the operation at any time.
* @returns {Promise<number>} A Promise which returns the computed average for the async-iterable sequence.
*/
export async function average(
source: AsyncIterable<any>,
options?: AverageOptions<any>
): Promise<number> {
const opts = options || { };
if (!opts.selector) {
opts.selector = identityAsync;
}
const { selector, signal, thisArg } = opts;
throwIfAborted(signal);
let sum = 0;
let count = 0;
for await (const item of wrapWithAbort(source, signal)) {
sum += await selector!.call(thisArg, item, signal);
count++;
}
if (count === 0) {
throw new Error('Empty collection');
}
return sum / count;
}
import { identityAsync } from '../util/identity';
import { wrapWithAbort } from './operators/withabort';
import { throwIfAborted } from '../aborterror';
/**
* Computes the average of the async-iterable sequence.
* @param source The source async-iterable sequence to compute the average.
* @param selector The selector used to get the value to average.
* @param thisArg An optional thisArg for the selector.
* @param signal An optional abort signal to cancel the operation at any time.
*/
export async function average(
source: AsyncIterable<number>,
selector?: (x: number, signal?: AbortSignal) => number | Promise<number>,
thisArg?: any,
signal?: AbortSignal
): Promise<number>;
export async function average<TSource>(
source: AsyncIterable<TSource>,
selector?: (x: TSource, signal?: AbortSignal) => number | Promise<number>,
thisArg?: any,
signal?: AbortSignal
): Promise<number>;
export async function average(
source: AsyncIterable<any>,
selector: (x: any, signal?: AbortSignal) => number | Promise<number> = identityAsync,
thisArg?: any,
signal?: AbortSignal
): Promise<number> {
throwIfAborted(signal);
let sum = 0;
let count = 0;
for await (const item of wrapWithAbort(source, signal)) {
sum += await selector.call(thisArg, item, signal);
count++;
}
if (count === 0) {
throw new Error('Empty collection');
}
return sum / count;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment