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