Path: blob/main/extensions/copilot/src/util/vs/base/common/collections.ts
13405 views
//!!! DO NOT modify, this file was COPIED from 'microsoft/vscode'12/*---------------------------------------------------------------------------------------------3* Copyright (c) Microsoft Corporation. All rights reserved.4* Licensed under the MIT License. See License.txt in the project root for license information.5*--------------------------------------------------------------------------------------------*/67/**8* An interface for a JavaScript object that9* acts a dictionary. The keys are strings.10*/11export type IStringDictionary<V> = Record<string, V>;1213/**14* An interface for a JavaScript object that15* acts a dictionary. The keys are numbers.16*/17export type INumberDictionary<V> = Record<number, V>;1819/**20* Groups the collection into a dictionary based on the provided21* group function.22*/23export function groupBy<K extends string | number | symbol, V>(data: readonly V[], groupFn: (element: V) => K): Partial<Record<K, V[]>> {24const result: Partial<Record<K, V[]>> = Object.create(null);25for (const element of data) {26const key = groupFn(element);27let target = result[key];28if (!target) {29target = result[key] = [];30}31target.push(element);32}33return result;34}3536export function groupByMap<K, V>(data: V[], groupFn: (element: V) => K): Map<K, V[]> {37const result = new Map<K, V[]>();38for (const element of data) {39const key = groupFn(element);40let target = result.get(key);41if (!target) {42target = [];43result.set(key, target);44}45target.push(element);46}47return result;48}4950export function diffSets<T>(before: ReadonlySet<T>, after: ReadonlySet<T>): { removed: T[]; added: T[] } {51const removed: T[] = [];52const added: T[] = [];53for (const element of before) {54if (!after.has(element)) {55removed.push(element);56}57}58for (const element of after) {59if (!before.has(element)) {60added.push(element);61}62}63return { removed, added };64}6566export function diffMaps<K, V>(before: Map<K, V>, after: Map<K, V>): { removed: V[]; added: V[] } {67const removed: V[] = [];68const added: V[] = [];69for (const [index, value] of before) {70if (!after.has(index)) {71removed.push(value);72}73}74for (const [index, value] of after) {75if (!before.has(index)) {76added.push(value);77}78}79return { removed, added };80}8182/**83* Computes the intersection of two sets.84*85* @param setA - The first set.86* @param setB - The second iterable.87* @returns A new set containing the elements that are in both `setA` and `setB`.88*/89export function intersection<T>(setA: Set<T>, setB: Iterable<T>): Set<T> {90const result = new Set<T>();91for (const elem of setB) {92if (setA.has(elem)) {93result.add(elem);94}95}96return result;97}9899export class SetWithKey<T> implements Set<T> {100private _map = new Map<unknown, T>();101102constructor(values: T[], private toKey: (t: T) => unknown) {103for (const value of values) {104this.add(value);105}106}107108get size(): number {109return this._map.size;110}111112add(value: T): this {113const key = this.toKey(value);114this._map.set(key, value);115return this;116}117118delete(value: T): boolean {119return this._map.delete(this.toKey(value));120}121122has(value: T): boolean {123return this._map.has(this.toKey(value));124}125126*entries(): IterableIterator<[T, T]> {127for (const entry of this._map.values()) {128yield [entry, entry];129}130}131132keys(): IterableIterator<T> {133return this.values();134}135136*values(): IterableIterator<T> {137for (const entry of this._map.values()) {138yield entry;139}140}141142clear(): void {143this._map.clear();144}145146forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: unknown): void {147this._map.forEach(entry => callbackfn.call(thisArg, entry, entry, this));148}149150[Symbol.iterator](): IterableIterator<T> {151return this.values();152}153154[Symbol.toStringTag]: string = 'SetWithKey';155}156157158