Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/util/vs/base/common/collections.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
/**
9
* An interface for a JavaScript object that
10
* acts a dictionary. The keys are strings.
11
*/
12
export type IStringDictionary<V> = Record<string, V>;
13
14
/**
15
* An interface for a JavaScript object that
16
* acts a dictionary. The keys are numbers.
17
*/
18
export type INumberDictionary<V> = Record<number, V>;
19
20
/**
21
* Groups the collection into a dictionary based on the provided
22
* group function.
23
*/
24
export function groupBy<K extends string | number | symbol, V>(data: readonly V[], groupFn: (element: V) => K): Partial<Record<K, V[]>> {
25
const result: Partial<Record<K, V[]>> = Object.create(null);
26
for (const element of data) {
27
const key = groupFn(element);
28
let target = result[key];
29
if (!target) {
30
target = result[key] = [];
31
}
32
target.push(element);
33
}
34
return result;
35
}
36
37
export function groupByMap<K, V>(data: V[], groupFn: (element: V) => K): Map<K, V[]> {
38
const result = new Map<K, V[]>();
39
for (const element of data) {
40
const key = groupFn(element);
41
let target = result.get(key);
42
if (!target) {
43
target = [];
44
result.set(key, target);
45
}
46
target.push(element);
47
}
48
return result;
49
}
50
51
export function diffSets<T>(before: ReadonlySet<T>, after: ReadonlySet<T>): { removed: T[]; added: T[] } {
52
const removed: T[] = [];
53
const added: T[] = [];
54
for (const element of before) {
55
if (!after.has(element)) {
56
removed.push(element);
57
}
58
}
59
for (const element of after) {
60
if (!before.has(element)) {
61
added.push(element);
62
}
63
}
64
return { removed, added };
65
}
66
67
export function diffMaps<K, V>(before: Map<K, V>, after: Map<K, V>): { removed: V[]; added: V[] } {
68
const removed: V[] = [];
69
const added: V[] = [];
70
for (const [index, value] of before) {
71
if (!after.has(index)) {
72
removed.push(value);
73
}
74
}
75
for (const [index, value] of after) {
76
if (!before.has(index)) {
77
added.push(value);
78
}
79
}
80
return { removed, added };
81
}
82
83
/**
84
* Computes the intersection of two sets.
85
*
86
* @param setA - The first set.
87
* @param setB - The second iterable.
88
* @returns A new set containing the elements that are in both `setA` and `setB`.
89
*/
90
export function intersection<T>(setA: Set<T>, setB: Iterable<T>): Set<T> {
91
const result = new Set<T>();
92
for (const elem of setB) {
93
if (setA.has(elem)) {
94
result.add(elem);
95
}
96
}
97
return result;
98
}
99
100
export class SetWithKey<T> implements Set<T> {
101
private _map = new Map<unknown, T>();
102
103
constructor(values: T[], private toKey: (t: T) => unknown) {
104
for (const value of values) {
105
this.add(value);
106
}
107
}
108
109
get size(): number {
110
return this._map.size;
111
}
112
113
add(value: T): this {
114
const key = this.toKey(value);
115
this._map.set(key, value);
116
return this;
117
}
118
119
delete(value: T): boolean {
120
return this._map.delete(this.toKey(value));
121
}
122
123
has(value: T): boolean {
124
return this._map.has(this.toKey(value));
125
}
126
127
*entries(): IterableIterator<[T, T]> {
128
for (const entry of this._map.values()) {
129
yield [entry, entry];
130
}
131
}
132
133
keys(): IterableIterator<T> {
134
return this.values();
135
}
136
137
*values(): IterableIterator<T> {
138
for (const entry of this._map.values()) {
139
yield entry;
140
}
141
}
142
143
clear(): void {
144
this._map.clear();
145
}
146
147
forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: unknown): void {
148
this._map.forEach(entry => callbackfn.call(thisArg, entry, entry, this));
149
}
150
151
[Symbol.iterator](): IterableIterator<T> {
152
return this.values();
153
}
154
155
[Symbol.toStringTag]: string = 'SetWithKey';
156
}
157
158