Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/util/vs/base/common/iterator.ts
13405 views
1
//!!! DO NOT modify, this file was COPIED from 'microsoft/vscode'
2
3
/*---------------------------------------------------------------------------------------------
4
* Copyright (c) Microsoft Corporation. All rights reserved.
5
* Licensed under the MIT License. See License.txt in the project root for license information.
6
*--------------------------------------------------------------------------------------------*/
7
8
import { isIterable } from './types';
9
10
export namespace Iterable {
11
12
export function is<T = unknown>(thing: unknown): thing is Iterable<T> {
13
return !!thing && typeof thing === 'object' && typeof (thing as Iterable<T>)[Symbol.iterator] === 'function';
14
}
15
16
const _empty: Iterable<never> = Object.freeze([]);
17
export function empty<T = never>(): readonly never[] {
18
return _empty as readonly never[];
19
}
20
21
export function* single<T>(element: T): Iterable<T> {
22
yield element;
23
}
24
25
export function wrap<T>(iterableOrElement: Iterable<T> | T): Iterable<T> {
26
if (is(iterableOrElement)) {
27
return iterableOrElement;
28
} else {
29
return single(iterableOrElement);
30
}
31
}
32
33
export function from<T>(iterable: Iterable<T> | undefined | null): Iterable<T> {
34
return iterable ?? (_empty as Iterable<T>);
35
}
36
37
export function* reverse<T>(array: ReadonlyArray<T>): Iterable<T> {
38
for (let i = array.length - 1; i >= 0; i--) {
39
yield array[i];
40
}
41
}
42
43
export function isEmpty<T>(iterable: Iterable<T> | undefined | null): boolean {
44
return !iterable || iterable[Symbol.iterator]().next().done === true;
45
}
46
47
export function first<T>(iterable: Iterable<T>): T | undefined {
48
return iterable[Symbol.iterator]().next().value;
49
}
50
51
export function some<T>(iterable: Iterable<T>, predicate: (t: T, i: number) => unknown): boolean {
52
let i = 0;
53
for (const element of iterable) {
54
if (predicate(element, i++)) {
55
return true;
56
}
57
}
58
return false;
59
}
60
61
export function every<T>(iterable: Iterable<T>, predicate: (t: T, i: number) => unknown): boolean {
62
let i = 0;
63
for (const element of iterable) {
64
if (!predicate(element, i++)) {
65
return false;
66
}
67
}
68
return true;
69
}
70
71
export function find<T, R extends T>(iterable: Iterable<T>, predicate: (t: T) => t is R): R | undefined;
72
export function find<T>(iterable: Iterable<T>, predicate: (t: T) => boolean): T | undefined;
73
export function find<T>(iterable: Iterable<T>, predicate: (t: T) => boolean): T | undefined {
74
for (const element of iterable) {
75
if (predicate(element)) {
76
return element;
77
}
78
}
79
80
return undefined;
81
}
82
83
export function filter<T, R extends T>(iterable: Iterable<T>, predicate: (t: T) => t is R): Iterable<R>;
84
export function filter<T>(iterable: Iterable<T>, predicate: (t: T) => boolean): Iterable<T>;
85
export function* filter<T>(iterable: Iterable<T>, predicate: (t: T) => boolean): Iterable<T> {
86
for (const element of iterable) {
87
if (predicate(element)) {
88
yield element;
89
}
90
}
91
}
92
93
export function* map<T, R>(iterable: Iterable<T>, fn: (t: T, index: number) => R): Iterable<R> {
94
let index = 0;
95
for (const element of iterable) {
96
yield fn(element, index++);
97
}
98
}
99
100
export function* flatMap<T, R>(iterable: Iterable<T>, fn: (t: T, index: number) => Iterable<R>): Iterable<R> {
101
let index = 0;
102
for (const element of iterable) {
103
yield* fn(element, index++);
104
}
105
}
106
107
export function* concat<T>(...iterables: (Iterable<T> | T)[]): Iterable<T> {
108
for (const item of iterables) {
109
if (isIterable(item)) {
110
yield* item;
111
} else {
112
yield item;
113
}
114
}
115
}
116
117
export function reduce<T, R>(iterable: Iterable<T>, reducer: (previousValue: R, currentValue: T) => R, initialValue: R): R {
118
let value = initialValue;
119
for (const element of iterable) {
120
value = reducer(value, element);
121
}
122
return value;
123
}
124
125
export function length<T>(iterable: Iterable<T>): number {
126
let count = 0;
127
for (const _ of iterable) {
128
count++;
129
}
130
return count;
131
}
132
133
/**
134
* Returns an iterable slice of the array, with the same semantics as `array.slice()`.
135
*/
136
export function* slice<T>(arr: ReadonlyArray<T>, from: number, to = arr.length): Iterable<T> {
137
if (from < -arr.length) {
138
from = 0;
139
}
140
if (from < 0) {
141
from += arr.length;
142
}
143
144
if (to < 0) {
145
to += arr.length;
146
} else if (to > arr.length) {
147
to = arr.length;
148
}
149
150
for (; from < to; from++) {
151
yield arr[from];
152
}
153
}
154
155
/**
156
* Consumes `atMost` elements from iterable and returns the consumed elements,
157
* and an iterable for the rest of the elements.
158
*/
159
export function consume<T>(iterable: Iterable<T>, atMost: number = Number.POSITIVE_INFINITY): [T[], Iterable<T>] {
160
const consumed: T[] = [];
161
162
if (atMost === 0) {
163
return [consumed, iterable];
164
}
165
166
const iterator = iterable[Symbol.iterator]();
167
168
for (let i = 0; i < atMost; i++) {
169
const next = iterator.next();
170
171
if (next.done) {
172
return [consumed, Iterable.empty()];
173
}
174
175
consumed.push(next.value);
176
}
177
178
return [consumed, { [Symbol.iterator]() { return iterator; } }];
179
}
180
181
export async function asyncToArray<T>(iterable: AsyncIterable<T>): Promise<T[]> {
182
const result: T[] = [];
183
for await (const item of iterable) {
184
result.push(item);
185
}
186
return result;
187
}
188
189
export async function asyncToArrayFlat<T>(iterable: AsyncIterable<T[]>): Promise<T[]> {
190
let result: T[] = [];
191
for await (const item of iterable) {
192
result = result.concat(item);
193
}
194
return result;
195
}
196
}
197
198