export type Group<T, TK> = { key: TK; items: T[] };

declare global {
    interface Array<T> {
        groupBy<T, TK>(keyFn: (item: T) => TK): Group<T, TK>[];
        intersect<T>(other: T[]): T[];
    }
}

if (!Array.prototype.groupBy)
    Array.prototype.intersect = function <T>(this: T[], other: T[]): T[] {
        const set = new Set<T>(this);
        return other.filter((i) => set.has(i));
    };
if (!Array.prototype.groupBy)
    Array.prototype.groupBy = function <T, TK>(
        this: T[],
        keyFn: (item: T) => TK,
    ): Group<T, TK>[] {
        const hash = new Map<TK, Group<T, TK>>();

        this.forEach((item) => {
            const key = keyFn(item);
            let group = hash.get(key);
            if (!group) {
                group = { key, items: [] };
                hash.set(key, group);
            }
            group.items.push(item);
        });

        return [...hash.values()];
    };
export default {};
