UNPKG

2.22 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|----------------------------------------------------------------------------*/
10/**
11 * Create an iterator of evenly spaced values.
12 *
13 * @param start - The starting value for the range, inclusive.
14 *
15 * @param stop - The stopping value for the range, exclusive.
16 *
17 * @param step - The distance between each value.
18 *
19 * @returns An iterator which produces evenly spaced values.
20 *
21 * #### Notes
22 * In the single argument form of `range(stop)`, `start` defaults to
23 * `0` and `step` defaults to `1`.
24 *
25 * In the two argument form of `range(start, stop)`, `step` defaults
26 * to `1`.
27 *
28 * #### Example
29 * ```typescript
30 * import { range } from '@lumino/algorithm';
31 *
32 * let stream = range(2, 4);
33 *
34 * Array.from(stream); // [2, 3]
35 * ```
36 */
37export function* range(
38 start: number,
39 stop?: number,
40 step?: number
41): IterableIterator<number> {
42 if (stop === undefined) {
43 stop = start;
44 start = 0;
45 step = 1;
46 } else if (step === undefined) {
47 step = 1;
48 }
49 const length = Private.rangeLength(start, stop, step);
50 for (let index = 0; index < length; index++) {
51 yield start + step * index;
52 }
53}
54
55/**
56 * The namespace for the module implementation details.
57 */
58namespace Private {
59 /**
60 * Compute the effective length of a range.
61 *
62 * @param start - The starting value for the range, inclusive.
63 *
64 * @param stop - The stopping value for the range, exclusive.
65 *
66 * @param step - The distance between each value.
67 *
68 * @returns The number of steps need to traverse the range.
69 */
70 export function rangeLength(
71 start: number,
72 stop: number,
73 step: number
74 ): number {
75 if (step === 0) {
76 return Infinity;
77 }
78 if (start > stop && step > 0) {
79 return 0;
80 }
81 if (start < stop && step < 0) {
82 return 0;
83 }
84 return Math.ceil((stop - start) / step);
85 }
86}