UNPKG

@lumino/algorithm

Version:

Lumino Algorithms and Iterators

246 lines (240 loc) 6.33 kB
// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. /*----------------------------------------------------------------------------- | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ import { iter, IterableOrArrayLike } from './iter'; /** * Find the first value in an iterable which matches a predicate. * * @param object - The iterable or array-like object to search. * * @param fn - The predicate function to apply to the values. * * @returns The first matching value, or `undefined` if no matching * value is found. * * #### Complexity * Linear. * * #### Example * ```typescript * import { find } from '@lumino/algorithm'; * * interface IAnimal { species: string, name: string }; * * function isCat(value: IAnimal): boolean { * return value.species === 'cat'; * } * * let data: IAnimal[] = [ * { species: 'dog', name: 'spot' }, * { species: 'cat', name: 'fluffy' }, * { species: 'alligator', name: 'pocho' } * ]; * * find(data, isCat).name; // 'fluffy' * ``` */ export function find<T>( object: IterableOrArrayLike<T>, fn: (value: T, index: number) => boolean ): T | undefined { let index = 0; let it = iter(object); let value: T | undefined; while ((value = it.next()) !== undefined) { if (fn(value, index++)) { return value; } } return undefined; } /** * Find the index of the first value which matches a predicate. * * @param object - The iterable or array-like object to search. * * @param fn - The predicate function to apply to the values. * * @returns The index of the first matching value, or `-1` if no * matching value is found. * * #### Complexity * Linear. * * #### Example * ```typescript * import { findIndex } from '@lumino/algorithm'; * * interface IAnimal { species: string, name: string }; * * function isCat(value: IAnimal): boolean { * return value.species === 'cat'; * } * * let data: IAnimal[] = [ * { species: 'dog', name: 'spot' }, * { species: 'cat', name: 'fluffy' }, * { species: 'alligator', name: 'pocho' } * ]; * * findIndex(data, isCat); // 1 * ``` */ export function findIndex<T>( object: IterableOrArrayLike<T>, fn: (value: T, index: number) => boolean ): number { let index = 0; let it = iter(object); let value: T | undefined; while ((value = it.next()) !== undefined) { if (fn(value, index++)) { return index - 1; } } return -1; } /** * Find the minimum value in an iterable. * * @param object - The iterable or array-like object to search. * * @param fn - The 3-way comparison function to apply to the values. * It should return `< 0` if the first value is less than the second. * `0` if the values are equivalent, or `> 0` if the first value is * greater than the second. * * @returns The minimum value in the iterable. If multiple values are * equivalent to the minimum, the left-most value is returned. If * the iterable is empty, this returns `undefined`. * * #### Complexity * Linear. * * #### Example * ```typescript * import { min } from '@lumino/algorithm'; * * function numberCmp(a: number, b: number): number { * return a - b; * } * * min([7, 4, 0, 3, 9, 4], numberCmp); // 0 * ``` */ export function min<T>( object: IterableOrArrayLike<T>, fn: (first: T, second: T) => number ): T | undefined { let it = iter(object); let value = it.next(); if (value === undefined) { return undefined; } let result = value; while ((value = it.next()) !== undefined) { if (fn(value, result) < 0) { result = value; } } return result; } /** * Find the maximum value in an iterable. * * @param object - The iterable or array-like object to search. * * @param fn - The 3-way comparison function to apply to the values. * It should return `< 0` if the first value is less than the second. * `0` if the values are equivalent, or `> 0` if the first value is * greater than the second. * * @returns The maximum value in the iterable. If multiple values are * equivalent to the maximum, the left-most value is returned. If * the iterable is empty, this returns `undefined`. * * #### Complexity * Linear. * * #### Example * ```typescript * import { max } from '@lumino/algorithm'; * * function numberCmp(a: number, b: number): number { * return a - b; * } * * max([7, 4, 0, 3, 9, 4], numberCmp); // 9 * ``` */ export function max<T>( object: IterableOrArrayLike<T>, fn: (first: T, second: T) => number ): T | undefined { let it = iter(object); let value = it.next(); if (value === undefined) { return undefined; } let result = value; while ((value = it.next()) !== undefined) { if (fn(value, result) > 0) { result = value; } } return result; } /** * Find the minimum and maximum values in an iterable. * * @param object - The iterable or array-like object to search. * * @param fn - The 3-way comparison function to apply to the values. * It should return `< 0` if the first value is less than the second. * `0` if the values are equivalent, or `> 0` if the first value is * greater than the second. * * @returns A 2-tuple of the `[min, max]` values in the iterable. If * multiple values are equivalent, the left-most values are returned. * If the iterable is empty, this returns `undefined`. * * #### Complexity * Linear. * * #### Example * ```typescript * import { minmax } from '@lumino/algorithm'; * * function numberCmp(a: number, b: number): number { * return a - b; * } * * minmax([7, 4, 0, 3, 9, 4], numberCmp); // [0, 9] * ``` */ export function minmax<T>( object: IterableOrArrayLike<T>, fn: (first: T, second: T) => number ): [T, T] | undefined { let it = iter(object); let value = it.next(); if (value === undefined) { return undefined; } let vmin = value; let vmax = value; while ((value = it.next()) !== undefined) { if (fn(value, vmin) < 0) { vmin = value; } else if (fn(value, vmax) > 0) { vmax = value; } } return [vmin, vmax]; }