UNPKG

6.33 kBPlain TextView Raw
1// Copyright (c) Jupyter Development Team.
2// Distributed under the terms of the Modified BSD License.
3/*-----------------------------------------------------------------------------
4| Copyright (c) 2014-2017, PhosphorJS Contributors
5|
6| Distributed under the terms of the BSD 3-Clause License.
7|
8| The full license is in the file LICENSE, distributed with this software.
9|----------------------------------------------------------------------------*/
10import { iter, IterableOrArrayLike } from './iter';
11
12/**
13 * Find the first value in an iterable which matches a predicate.
14 *
15 * @param object - The iterable or array-like object to search.
16 *
17 * @param fn - The predicate function to apply to the values.
18 *
19 * @returns The first matching value, or `undefined` if no matching
20 * value is found.
21 *
22 * #### Complexity
23 * Linear.
24 *
25 * #### Example
26 * ```typescript
27 * import { find } from '@lumino/algorithm';
28 *
29 * interface IAnimal { species: string, name: string };
30 *
31 * function isCat(value: IAnimal): boolean {
32 * return value.species === 'cat';
33 * }
34 *
35 * let data: IAnimal[] = [
36 * { species: 'dog', name: 'spot' },
37 * { species: 'cat', name: 'fluffy' },
38 * { species: 'alligator', name: 'pocho' }
39 * ];
40 *
41 * find(data, isCat).name; // 'fluffy'
42 * ```
43 */
44export function find<T>(
45 object: IterableOrArrayLike<T>,
46 fn: (value: T, index: number) => boolean
47): T | undefined {
48 let index = 0;
49 let it = iter(object);
50 let value: T | undefined;
51 while ((value = it.next()) !== undefined) {
52 if (fn(value, index++)) {
53 return value;
54 }
55 }
56 return undefined;
57}
58
59/**
60 * Find the index of the first value which matches a predicate.
61 *
62 * @param object - The iterable or array-like object to search.
63 *
64 * @param fn - The predicate function to apply to the values.
65 *
66 * @returns The index of the first matching value, or `-1` if no
67 * matching value is found.
68 *
69 * #### Complexity
70 * Linear.
71 *
72 * #### Example
73 * ```typescript
74 * import { findIndex } from '@lumino/algorithm';
75 *
76 * interface IAnimal { species: string, name: string };
77 *
78 * function isCat(value: IAnimal): boolean {
79 * return value.species === 'cat';
80 * }
81 *
82 * let data: IAnimal[] = [
83 * { species: 'dog', name: 'spot' },
84 * { species: 'cat', name: 'fluffy' },
85 * { species: 'alligator', name: 'pocho' }
86 * ];
87 *
88 * findIndex(data, isCat); // 1
89 * ```
90 */
91export function findIndex<T>(
92 object: IterableOrArrayLike<T>,
93 fn: (value: T, index: number) => boolean
94): number {
95 let index = 0;
96 let it = iter(object);
97 let value: T | undefined;
98 while ((value = it.next()) !== undefined) {
99 if (fn(value, index++)) {
100 return index - 1;
101 }
102 }
103 return -1;
104}
105
106/**
107 * Find the minimum value in an iterable.
108 *
109 * @param object - The iterable or array-like object to search.
110 *
111 * @param fn - The 3-way comparison function to apply to the values.
112 * It should return `< 0` if the first value is less than the second.
113 * `0` if the values are equivalent, or `> 0` if the first value is
114 * greater than the second.
115 *
116 * @returns The minimum value in the iterable. If multiple values are
117 * equivalent to the minimum, the left-most value is returned. If
118 * the iterable is empty, this returns `undefined`.
119 *
120 * #### Complexity
121 * Linear.
122 *
123 * #### Example
124 * ```typescript
125 * import { min } from '@lumino/algorithm';
126 *
127 * function numberCmp(a: number, b: number): number {
128 * return a - b;
129 * }
130 *
131 * min([7, 4, 0, 3, 9, 4], numberCmp); // 0
132 * ```
133 */
134export function min<T>(
135 object: IterableOrArrayLike<T>,
136 fn: (first: T, second: T) => number
137): T | undefined {
138 let it = iter(object);
139 let value = it.next();
140 if (value === undefined) {
141 return undefined;
142 }
143 let result = value;
144 while ((value = it.next()) !== undefined) {
145 if (fn(value, result) < 0) {
146 result = value;
147 }
148 }
149 return result;
150}
151
152/**
153 * Find the maximum value in an iterable.
154 *
155 * @param object - The iterable or array-like object to search.
156 *
157 * @param fn - The 3-way comparison function to apply to the values.
158 * It should return `< 0` if the first value is less than the second.
159 * `0` if the values are equivalent, or `> 0` if the first value is
160 * greater than the second.
161 *
162 * @returns The maximum value in the iterable. If multiple values are
163 * equivalent to the maximum, the left-most value is returned. If
164 * the iterable is empty, this returns `undefined`.
165 *
166 * #### Complexity
167 * Linear.
168 *
169 * #### Example
170 * ```typescript
171 * import { max } from '@lumino/algorithm';
172 *
173 * function numberCmp(a: number, b: number): number {
174 * return a - b;
175 * }
176 *
177 * max([7, 4, 0, 3, 9, 4], numberCmp); // 9
178 * ```
179 */
180export function max<T>(
181 object: IterableOrArrayLike<T>,
182 fn: (first: T, second: T) => number
183): T | undefined {
184 let it = iter(object);
185 let value = it.next();
186 if (value === undefined) {
187 return undefined;
188 }
189 let result = value;
190 while ((value = it.next()) !== undefined) {
191 if (fn(value, result) > 0) {
192 result = value;
193 }
194 }
195 return result;
196}
197
198/**
199 * Find the minimum and maximum values in an iterable.
200 *
201 * @param object - The iterable or array-like object to search.
202 *
203 * @param fn - The 3-way comparison function to apply to the values.
204 * It should return `< 0` if the first value is less than the second.
205 * `0` if the values are equivalent, or `> 0` if the first value is
206 * greater than the second.
207 *
208 * @returns A 2-tuple of the `[min, max]` values in the iterable. If
209 * multiple values are equivalent, the left-most values are returned.
210 * If the iterable is empty, this returns `undefined`.
211 *
212 * #### Complexity
213 * Linear.
214 *
215 * #### Example
216 * ```typescript
217 * import { minmax } from '@lumino/algorithm';
218 *
219 * function numberCmp(a: number, b: number): number {
220 * return a - b;
221 * }
222 *
223 * minmax([7, 4, 0, 3, 9, 4], numberCmp); // [0, 9]
224 * ```
225 */
226export function minmax<T>(
227 object: IterableOrArrayLike<T>,
228 fn: (first: T, second: T) => number
229): [T, T] | undefined {
230 let it = iter(object);
231 let value = it.next();
232 if (value === undefined) {
233 return undefined;
234 }
235 let vmin = value;
236 let vmax = value;
237 while ((value = it.next()) !== undefined) {
238 if (fn(value, vmin) < 0) {
239 vmin = value;
240 } else if (fn(value, vmax) > 0) {
241 vmax = value;
242 }
243 }
244 return [vmin, vmax];
245}